问题描述
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
样例输入
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
样例输出
5
解题思路:dfs遍历,注意给学生分配房间,还有要减枝,不然容易超时
代码如下:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int map[101][101];
vector<int> classroom[101];//分配的教室
int min_class = 999999,n;
void dfs(int classes,int stu_tag)
{
int i,j;
if(stu_tag==n+1)//学生人数达到了
{
if(min_class>classes)
{
min_class = classes;
}
return;
}
if(classes>=min_class)//减枝,去掉没用的遍历
return;
for(i=1;i<=classes;i++)//遍历教室
{
bool flag=false;
int size = classroom[i].size();//得到房间的总人数
for(j=0;j<size;j++)//遍历房间里的学生
{
if(map[stu_tag][classroom[i][j]]==1)//这个学生有教室并且学生跟要加进来的学生认识
{//classroom[i][j]表示学生
flag=true;
break;
}
}
if(!flag)//说明这个教室没认识的人
{
classroom[i].push_back(stu_tag);//给它分配房间
dfs(classes,stu_tag+1);//学生人数+1
classroom[i].pop_back();
}
}
//这些教室都有人,则新增一间教室
classroom[i].push_back(stu_tag);//给它分配房间
dfs(classes+1,stu_tag+1);
classroom[i].pop_back();
}
int main()
{
int m,i,a,b,count=0;
cin >> n;
cin >> m;//m行数据
memset(map,0,sizeof(map));
memset(classroom,0,sizeof(classroom));
for(i=0;i<m;i++)
{
cin >> a >> b;
map[a][b]=1;
map[b][a]=1;
}
dfs(0,1);
cout << min_class << endl;
return 0;
}