【转】POJ1129-Channel Allocation:DFS 四色定理 剪枝枚举
#include<iostream> #include<cstdio> #include<cstring> using namespace std; bool g[26][26]; int used[26]; int n; //id 是当下着色结点 color是限制的颜色数量 bool dfs(int id, int color) { bool flag;// 标记 节点id 染第i种色成功与否 for(int i=0; i<color; i++) { flag=true; used[id]=i;// 当前节点id涂第i种颜色 for(int j=0; j<id; j++)// 判断id的已涂过色的邻接点是否使用了第i种颜色 if(g[id][j]&&used[id]==used[j]) { flag=false;// 该i颜色已经使用过了 break;// 跳出转而进行第i+1颜色的尝试 } if( flag && ( id==n-1 || dfs(id+1, color) ) )// 搜索终点是 全部节点都已涂色成功 从而不必再dfs了 return true; } return false;// 节点id进行color个颜色的尝试 未能成功着色 也就是说color个颜色都用过了 id节点无色可染 } int main() { char adjacent[50]; while(scanf("%d", &n)&&n) { memset(g, 0, sizeof(g)); memset(used, 0, sizeof(used)); bool one = true; for(int i=0; i<n; i++) { scanf("%s", adjacent); for(int j=2; adjacent[j]!='\0'; j++, one=false) { g[i][adjacent[j]-'A']=true; g[adjacent[j]-'A'][i]=true; } } // 根据四色定理 可知颜色不超过四种 则逐一枚举 可行性剪枝 if(one) printf("1 channel needed.\n"); else if(dfs(1,2)) printf("2 channecls needed.\n"); else if(dfs(1,3)) printf("3 channels needed.\n"); else printf("4 channels needed.\n"); } return 0; }