题记
安排每一位同学之前先看看之前的考场能否让这位同学安排进去,也就是依次遍历这位同学是否跟这个教室里所有同学都不认识。因为不好证明这样做就是正确的,所以保险起见还要考虑为这个同学开辟一个新的考场的情况。注意回溯!!!还有回溯的时候是判断当前计算的考场数是否大于等于已经计算的最小考场数roomMin,如果是直接retun。
#include <iostream>
using namespace std;
const int Maxn=100+5;
int relation[Maxn][Maxn];
int room[Maxn][Maxn];
int roomMin;//房间数目的最小值
int n,m;
void dfs(int index,int res){
if(res>=roomMin) //房间数目比人数还多(直接不用考虑了)
return;
if(index>n){ //安排的人数大于学生人数了
if(res<roomMin)
roomMin=res;
return;
}
for(int i=1;i<=res;i++){
int position=0;//如果这个学生可以进i考场,position来确定他的位置
while(room[i][position]&&!relation[index][room[i][position]])
position++;
if(!room[i][position]){
room[i][position]=index;
dfs(index+1,res);
room[i][position]=0;
}
}
room[res+1][0]=index;//为这个学生开辟一个新的考场
dfs(index+1,res+1);
room[res+1][0]=0;
}
int main()
{
ios::sync_with_stdio(false);
int a,b;
cin>>n;
cin>>m;
roomMin=n;
for(int i=0;i<m;i++){
cin>>a>>b;
relation[a][b]=relation[b][a]=1;
}
dfs(1,0);
cout<<roomMin<<endl;
return 0;
}