标签:
#include<stdio.h> #include<string.h> int nn; //用来判断是否有重复的连通 int ff[100005];//ff[x]表示x的父节点 int qq[100005];//标记数组 int ss[100005];//ss[x]表示x的秩 void ii(int n) //初始化 { for (int i=0;i<n;i++) { ff[i] = i; ss[i] = 1; } } int dd(int x) //带路径压缩的查找 { if (x!=ff[x]) { ff[x] = dd(ff[x]); } return ff[x]; } int cc(int a,int b,int t) //按秩合并 { int ta=dd(a); int tb=dd(b); if (ta != tb) { if (ss[ta] >= ss[tb]) { ff[tb]=ta; if(ss[ta] == ss[tb]) ss[ta]++; } else ff[ta] = tb; t++; } return t; } int main() { int i,m,a,b,t,k,j,n; //int t 为需要增加的路 while(~scanf("%d%d",&n,&m)) { if(!n) return 0; ii(100000); memset(qq,0,sizeof(qq)); while(m--) { t=0; scanf("%d%d",&a,&b); cc(a,b,t); qq[a]=qq[b]=1; } for (i=1,t=0;i<=n;i++) { if (qq[i]==0) { for (j=1;j<=n;j++) { if(qq[j]) t=cc(i,j,t); } qq[i]=1; } } printf("%d\n",t); } return 0; }
首先套用并查集模板。
分析:要使每个城镇都能连通,实际上是要使每个城镇的所指的根都是同一个城镇,那么这样每个城镇都可以互相连通。
判断需要连通几条路主要的代码就在int cc()里面的if判断中,如果指的根不同,那么就需要t++
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0
1 0 2 998Huge input, scanf is recommended.HintHint
标签:
原文地址:http://blog.csdn.net/xinwen1995/article/details/45741801