标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 12799 | Accepted: 6558 |
Description
Input
Output
Sample Input
2 A: B: 4 A:BC B:ACD C:ABD D:BC 4 A:BCD B:ACD C:ABD D:ABC 0
Sample Output
1 channel needed. 3 channels needed. 4 channels needed.
题意:在给定的图中涂色,使所有的结点都涂上色且相邻结点颜色不能相同,求最小需要的颜色
思路:dfs,由四色定理可知最多只需四种颜色,故只需遍历四种颜色,从结点1,结点2,...结点n,利用贪心选择性质从颜色1开始涂,涂满时第一个解一定是最优解,图不一定是连通图,因此只能dfs(u){...dfs(u+1)..} 边界为n,而不能直接向四周扩展
/* poj1129_dfs 16ms */ #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> using namespace std; const int maxn=30; const int INF=(1<<28); int N; vector<int> G[maxn]; int color[maxn]; bool vis[maxn][6];//第i个结点禁用颜色j int ans,cnt; bool flag; void put(int u,int cor) { color[u]=cor; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; vis[v][cor]=1; } } void remov(int u,int cor) { color[u]=0; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; vis[v][cor]=0; } } void dfs(int u) { if(flag) return; if(color[u]) return; if(u==N+1){ ans=cnt; flag=1;return; } for(int i=1;i<=4;i++){ if(!vis[u][i]){ put(u,i); bool tag=0; if(i>cnt){ tag=1; cnt++; } dfs(u+1); remov(u,i); if(tag) cnt--; } } } int main() { while(cin>>N,N){ for(int i=1;i<=N;i++) G[i].clear(); getchar(); for(int u=1;u<=N;u++){ char ch; cin>>ch>>ch; while((ch=getchar())!=‘\n‘) G[u].push_back(ch-‘A‘+1); } ans=cnt=0; flag=0; memset(color,0,sizeof(color)); memset(vis,0,sizeof(vis)); dfs(1); if(ans==1) printf("1 channel needed.\n"); else printf("%d channels needed.\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/--560/p/4337404.html