问题描述
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深度搜索,遍历目前已有的房间,判断这个人是否可以放入,若是,则放入,继续dfs。遍历完可以把他放到新的房间里再dfs。找出所需最少的房间。注意剪枝。
#include<iostream>
#include<vector>
using namespace std;
bool is_friend[100][100];
int n,m;
int minroom=1000;
int theroom[102][102];//不同房间的人
int cnt[102];//不同房间的人的数量
void dfs(int person,int roomnum)
{
if(roomnum>=minroom)
{//剪枝
return;
}
if(person>n)
{
minroom=min(minroom, roomnum);
return;
}
for(int i=1;i<=roomnum;i++)
{
int flag=0;
for(int j=1;j<=cnt[i];j++)
{
if(is_friend[person][theroom[i][j]]==true)
{
flag=1;
break;
}
}
if(flag==0)//可以放在这个屋子里
{
theroom[i][++cnt[i]]=person;
dfs(person+1,roomnum);
cnt[i]--;
}
}
//放到新的屋子里
theroom[roomnum+1][++cnt[roomnum+1]]=person;
dfs(person+1,roomnum+1);
cnt[roomnum+1]--;
return;
}
int main()
{
cin>>n>>m;
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
is_friend[a][b]=is_friend[b][a]=true;
}
dfs(1,0);
cout<<minroom<<endl;
return 0;
}