hdu 1232 畅通工程 求连通分支数
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1232
直接求连通分支数,有重边不影响dfs ,有n个连通分支块,就恰好最少需要n-1条边
代码:
#include<iostream> #include<vector> #include<cstring> #include<cstdio> using namespace std; vector<int> G[1000]; int maxn; bool vis[1000]; void dfs(int u) { vis[u]=1; int d=G[u].size(); for(int i=0;i<d;i++) { int v=G[u][i]; if(!vis[v]) dfs(v); } } int main() { int n,m; while(cin>>n>>m) { if(n==0) break; memset(vis,0,sizeof(vis)); for(int i=0;i<1000;i++) G[i].clear(); int a,b; for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); G[a-1].push_back(b-1); G[b-1].push_back(a-1); } int cc=0; for(int i=0;i<n;i++) { if(!vis[i]) { cc++; dfs(i); } } cout<<cc-1<<endl; } }
这种方法还是很复杂啊,并查集求连通分支很简单:
#include<set> #include<cstdio> #include<iostream> using namespace std; int p[1000]; int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } int main() { int n,m; int a,b; while(cin>>n>>m) { for(int i=0;i<n;i++) p[i]=i; for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); int x=find(a-1); int y=find(b-1); if(x!=y) { p[x]=y; } } set<int> setv; for(int i=0;i<n;i++) { setv.insert(find(i)); } cout<<setv.size()-1<<endl; } }
posted on 2013-09-09 17:02 814jingqi的ACM 阅读(178) 评论(0) 编辑 收藏 举报