标签:
#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