一开始,看着这个题,就是和图的M可着色问题类似。注意,是寻找最小的M,也就是寻找最少的配色方案
于是,按照以前课上的讲法,就很暴力。。。
#include<iostream>
using namespace std;
int n;
const int maxn=105;
int a[maxn][maxn];
int flag[maxn];//是否安排过考场
int min=9999;
int sum=0;
int f=0;
int ok(int now){
for(int i=1;i<now;i++){
if(a[now][i]==1&&flag[now]==flag[i]) return 0;
}
return 1;
}
void dfs(int now){
if(now>n){
f=1;
return ;
}
for(int i=1;i<=sum;i++){
flag[now]=i;
if(ok(now)) dfs(now+1);
}
}
int main(){
cin>>n;
int m;
cin>>m;
int x,y;
for(int i=1;i<=m;i++){
cin>>x>>y;
a[x][y]=a[y][x]=1;//代表x和y两个人认识
}
while(1){
sum++;
dfs(1);
if(f){
cout<<sum<<endl;
return 0;
}
}
}
果不其然,就超时了
在网上搜了搜但是感觉思路很繁琐
只要在上述代码中稍加改变就可以了
AC代码:
#include<iostream>
using namespace std;
int n;
const int maxn=105;
int a[maxn][maxn];
int flag[maxn];//安排考场
int min1=9999;
int sum=0;
int f=0;
int ok(int now){
for(int i=1;i<now;i++){
if(a[now][i]==1&&flag[now]==flag[i]) return 0;
}
return 1;
}
void dfs(int now,int sum){
if(sum>=min1) return ;//剪枝
if(now>n){
min1=min(min1,sum);
return ;
}
for(int i=1;i<=sum;i++){
flag[now]=i;
if(ok(now)) dfs(now+1,sum);
}
flag[now]=sum+1;//新申请一个考场
dfs(now+1,sum+1);
}
int main(){
cin>>n;
int m;
cin>>m;
int x,y;
for(int i=1;i<=m;i++){
cin>>x>>y;
a[x][y]=a[y][x]=1;//代表x和y两个人认识
}
dfs(1,0);
cout<<min1<<endl;
}
注意剪枝处的等号,会引起最后一个点超时的!!!