蓝桥杯:分考场问题 https://www.dotcpp.com/oj/problem1874.html
题目描述
n个人参加某项特殊考试。 为了公平,要求任何两个认识的人不能分在同一个考场。 求是少需要分几个考场才能满足条件。
输入
第一行,一个整数n(1<n<100),表示参加考试的人数。 第二行,一个整数m,表示接下来有m行数据 以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。 输出 一行一个整数,表示最少分几个考场。
样例输入
5 8 1 2 1 3 1 4 2 3 2 4 2 5 3 4 4 5
样例输出
4
思路(dfs+剪枝)
这个题,一般简单的贪心法是考虑不周的,比如把和自己不认识的同学都加入一个考场,此时没有考虑其他同学之间是否相互认识。这个题可以抽象为:存在一个无向图,要求给图中的点涂色,并且有线连接的点之间不能是同一种颜色。 但是这不是四色问题,因为同学之间的关系所形成的无向图不一定是平面图,对于非平面图,所用到的颜色就可能超过四种。 所以我们每次dfs(id),判断前num个房间是不是可以放进去,不能放进去就在开辟一个房间,能放进去也不用担心是不是最优情况,我们都遍历一遍,回溯,找到最优情况
代码
#include <iostream>
using namespace std
;
int mp
[100][100];
int room
[100][100];
int cnt
[100];
int n
,m
,ans
=100;
void dfs(int num
,int id
)
{
if(num
>=ans
) return;
if(id
==n
+1)
{
ans
=min(ans
,num
);
return ;
}
for(int i
=1;i
<=num
;i
++)
{
int k
=cnt
[i
];
int sign
=1;
for(int j
=1;j
<=k
;j
++)
{
if(mp
[id
][room
[i
][j
]])
{
sign
=0;
break;
}
}
if(sign
)
{
room
[i
][++cnt
[i
]]=id
;
dfs(num
,id
+1);
--cnt
[i
];
}
}
room
[num
+1][++cnt
[num
+1]]=id
;
dfs(num
+1,id
+1);
--cnt
[num
+1];
}
int main(int argc
, char const *argv
[])
{
cin
>>n
>>m
;
for(int i
=1;i
<=m
;i
++)
{
int x
,y
;
cin
>>x
>>y
;
mp
[x
][y
]=mp
[y
][x
]=1;
}
dfs(1,1);
cout
<<ans
<<endl
;
return 0;
}
代码解释
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std
;
const int maxn
= 110;
const int inf
= 0x3f3f3f3f;
int gra
[maxn
][maxn
];
int cun
[maxn
][maxn
];
int cnt
[maxn
];
int res
=inf
;
int n
,m
;
void solve(int id
,int num
){
if(num
>=res
){
return;
}
if(id
>n
){
res
=min(res
,num
);
return;
}
for(int i
=1;i
<=num
;i
++){
int sz
=cnt
[i
];
int jishu
=0;
for(int j
=1;j
<=sz
;j
++){
if(gra
[id
][cun
[i
][j
]]==0){
jishu
++;
}
}
if(jishu
==sz
){
cun
[i
][++cnt
[i
]]=id
;
solve(id
+1,num
);
cnt
[i
]--;
}
}
cun
[num
+1][++cnt
[num
+1]]=id
;
solve(id
+1,num
+1);
--cnt
[num
+1];
}
int main(){
scanf("%d%d",&n
,&m
);
memset(gra
,0,sizeof(gra
));
memset(cnt
,0,sizeof(cnt
));
while(m
--){
int a
,b
;
scanf("%d%d",&a
,&b
);
gra
[a
][b
]=gra
[b
][a
]=1;
}
solve(1,0);
printf("%d\n",res
);
return 0;
}