题解:P8653 [蓝桥杯 2017 国 C] 分考场(假题:最小色数)
Heart_of_Iron · · 题解
回溯法深度搜索解空间(dfs)
对于当前问题 dfs(x,kc);即是第
一但入了考场,就递归 dfs 找下一规模问题,知道找到一个解,和当前值比较,如果更优就更新。
代码:
#include<bits/stdc++.h>
using namespace std;
int M[101][101];//关系矩阵
int room[101][101];//考场矩阵
int ans=99999;//存放最优解
int n,m;
void dfs(int num,int kc)
{
if(kc>=ans)return ;//剪枝
if(num>n){//更新
ans=kc;
}else{
for(int i=1;i<=kc;i++){
int k=0;
while(room[i][k]&&M[num][room[i][k]]==0){
//该位置有人且没有关系继续找空位
//如果有关系就不能在一个考场,跳出循环找下一个考场
k++;
}
if(room[i][k]==0){
room[i][k]=num;//入考场
dfs(num+1,kc);//递归
room[i][k]=0;//回溯
}
}
room[kc+1][0]=num;//去下一个考场
dfs(num+1,kc+1);//递归
room[kc+1][0]=0;//回溯
}
}
int main()
{
memset(M,0,sizeof M);
memset(room,0,sizeof room);
cin>>n>>m;
int a,b;
for(int i=0;i<m;i++){
cin>>a>>b;
M[a][b]=1;
M[b][a]=1;
}
dfs(1,1);
cout<<ans;
return 0;
}