uva 193 Graph Coloring
2014-10-30 15:26
253 查看
题目大意:
给出一个图,让你给一些点染成黑色,要求相连的两个点不能同时被染色,求最大的染色数量。
分析:
数据量不是很大,回溯法可以解决,不过单纯的回溯会TLE,要加上一点剪枝。
由于是递归时是从1到n,所以如果当前染色点加上剩余的点都比当前的最优答案小的话,是肯定不能构成最大解的,直接return。if(n+ans-i<Max) return;
提供了两种AC的代码,大体思路都是相同的。区别是递归的方式有些不同,第一种采取了一种循环的方式,而第二种没有使用循环,直接是将点从1到n进行递归。显然第二种在时间效率上更高。
第一种是按照图的搜索进行,这样的就是n^n,因为每次都会扩展n个节点。
而第二种是按照顺序进行搜索,每次只扩展两个节点,2^n,效率高很多。
对递归的理解还是不清晰。有清晰的理解请留言指教。不胜感激。
给出一个图,让你给一些点染成黑色,要求相连的两个点不能同时被染色,求最大的染色数量。
分析:
数据量不是很大,回溯法可以解决,不过单纯的回溯会TLE,要加上一点剪枝。
由于是递归时是从1到n,所以如果当前染色点加上剩余的点都比当前的最优答案小的话,是肯定不能构成最大解的,直接return。if(n+ans-i<Max) return;
#include<algorithm> #include<cmath> #include<cstring> #include<string> #include<cstdio> #include<iostream> using namespace std; int n,m; int a[110][110]; int vis[110]; int res[110]; int Max=0; void dfs(int ans) { if(ans>Max) { Max=ans; memcpy(res,vis,sizeof(vis)); } for(int i=1; i<=n; i++) { if(ans+n-i<Max) return; if(vis[i]) continue; int ok=1; for(int j=1; j<=n; j++) { if(a[i][j]&&vis[j]) { ok=0; break; } } if(ok) { vis[i]=1; dfs(ans+1); vis[i]=0; } } } int main() { int t; cin>>t; while(t--) { scanf("%d%d",&n,&m); int p,q; Max=0; memset(vis,0,sizeof(vis)); memset(a,0,sizeof(a)); for(int i=1; i<=m; i++) { scanf("%d%d",&p,&q); a[p][q]=1; a[q][p]=1; } dfs(0); cout<<Max<<endl; int fi=1; for(int i=1; i<=n; i++) { if(res[i]) { if(fi) { cout<<i; fi=0; } else printf(" %d",i); } } cout<<endl; } return 0; }
#include<algorithm> #include<cmath> #include<cstring> #include<string> #include<cstdio> #include<iostream> using namespace std; int n,m; int a[110][110]; int vis[110]; int res[110]; int Max=0; void dfs(int i,int ans) { if(i>n&&ans>Max) { Max=ans; memcpy(res,vis,sizeof(vis)); return ; } int ok=1; for(int j=1; j<=n; j++) { if(a[i][j]&&vis[j]) { ok=0; break; } } if(n+ans-i<Max) return; vis[i]=1; if(ok) dfs(i+1,ans+1); vis[i]=0; dfs(i+1,ans); } int main() { int t; cin>>t; while(t--) { scanf("%d%d",&n,&m); int aa,bb; Max=0; memset(vis,0,sizeof(vis)); memset(a,0,sizeof(a)); for(int i=1; i<=m; i++) { scanf("%d%d",&aa,&bb); a[aa][bb]=1; a[bb][aa]=1; } dfs(1,0); cout<<Max<<endl; // cout<<res[1]; int fi=1; for(int i=1; i<=n; i++) { if(res[i]) { if(fi) { cout<<i; fi=0; } else printf(" %d",i); } } cout<<endl; } return 0; }
提供了两种AC的代码,大体思路都是相同的。区别是递归的方式有些不同,第一种采取了一种循环的方式,而第二种没有使用循环,直接是将点从1到n进行递归。显然第二种在时间效率上更高。
第一种是按照图的搜索进行,这样的就是n^n,因为每次都会扩展n个节点。
而第二种是按照顺序进行搜索,每次只扩展两个节点,2^n,效率高很多。
对递归的理解还是不清晰。有清晰的理解请留言指教。不胜感激。
相关文章推荐
- UVA - 193 Graph Coloring
- uva 193 - Graph Coloring
- uva 193 Graph Coloring(回溯)
- uva193 - Graph Coloring
- uva 193 Graph Coloring
- UVA 193 - Graph Coloring
- uva 193 Graph Coloring
- uva 193 Graph Coloring(DFS)
- uva 193 - Graph Coloring
- UVA - 193 Graph Coloring
- UVA - 193 Graph Coloring(回溯)
- UVA 193 Graph Coloring
- uva 193 Graph Coloring( 图染色 ) DFS+回溯
- UVa 193 - Graph Coloring(graph theory, brute force, backtracking, NP-complete, maximum independent set.)
- UVa 193 - Graph Coloring
- poj 1419 Graph Coloring uva 193 - Graph Coloring (图着色问题,dfs)
- UVa 193 - Graph Coloring
- Uva 193 - Graph Coloring
- UVA 193 - Graph Coloring
- uva193 - Graph Coloring