sdut 1488 连通分量的个数(并查集)
生活随笔
收集整理的这篇文章主要介绍了
sdut 1488 连通分量的个数(并查集)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
数据结构实验:连通分量个数
Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic DiscussProblem Description
在无向图中,如果从顶点vi到顶点vj有路径,则称vi和vj连通。如果图中任意两个顶点之间都连通,则称该图为连通图, 否则,称该图为非连通图,则其中的极大连通子图称为连通分量,这里所谓的极大是指子图中包含的顶点个数极大。 例如:一个无向图有5个顶点,1-3-5是连通的,2是连通的,4是连通的,则这个无向图有3个连通分量。Input
第一行是一个整数T,表示有T组测试样例(0 < T <= 50)。每个测试样例开始一行包括两个整数N,M,(0 < N <= 20,0 <= M <= 200) 分别代表N个顶点,和M条边。下面的M行,每行有两个整数u,v,顶点u和顶点v相连。Output
每行一个整数,连通分量个数。Example Input
2 3 1 1 2 3 2 3 2 1 2Example Output
2 1Hint
Author
#include <bits/stdc++.h>> using namespace std; int pre[25]; int find(int i) {int r=i;while(pre[r]!=r)r=pre[r];int j;while(i!=r){j=pre[i];pre[i]=r;i=j;}return r; } void join(int a,int b) {if(find(a)!=find(b))pre[find(a)]=find(b); } int main() {int t,m,n,p,q;int a[25];cin>>t;while(t--){int ans=0;cin>>n>>m;for(int i=0;i<=n;++i)pre[i]=i;memset(a,0,sizeof(a));for(int i=0;i<m;++i){cin>>p>>q;join(p,q);}for(int i=0;i<=n;++i)a[find(i)]=1;for(int i=1;i<=n;++i)//要从1开始if(a[i])ans++;cout<<ans<<endl;} }网上的DFS可以过的: #include<iostream> #include<string.h> using namespace std; typedef struct graph {int ma[21][21];int v,a; }mg; int vis[21]; void dfs(mg &g,int n) {vis[n]=1;for(int i=1;i<=g.v;i++){if(!vis[i]&&g.ma[n][i])dfs(g,i);} } int main() {int t,m,n,a,b,count;cin>>t;while(t--){mg g;cin>>n>>m;g.v=n;g.a=m;memset(g.ma,0,sizeof(g.ma));memset(vis,0,sizeof(vis));for(int i=0;i<m;i++){cin>>a>>b;g.ma[a][b]=g.ma[b][a]=1;}count=0;//连通分量的个数//没有被访问过的顶点,做一次深搜就能找到一个新的连通分量for(int i=1;i<=n;i++){if(!vis[i]){dfs(g,i);count++;}}cout<<count<<endl;}return 0; }
总结
以上是生活随笔为你收集整理的sdut 1488 连通分量的个数(并查集)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: HDU 1232畅通工程
- 下一篇: sdut 2506 完美网络(优先队列)