题目
一、分析
简单的并查集算法的使用
二、代码
1.
代码如下(示例):
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
int pre[1005];
void init(int n)
{
for(int i=0;i<=n;i++)
{
pre[i]=i;
}
}
int find(int x)
{
if(pre[x]==x)
return x;
int j=find(pre[x]);
return pre[x]=j;
}
void union_1(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
}
}
int main()
{
int t;
int n,m,a,b;
int s;
scanf("%d",&t);
while(t--)
{
s=0;
scanf("%d%d",&n,&m);
init(n);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
union_1(a,b);
}
for(int i=1;i<=n;i++)
{
if(i==pre[i])
s++;
}
printf("%d\n",s);
}
return 0;
}
2.
代码如下(示例):
#include <iostream>
#include <cstring>
#include<stdio.h>
#define inf 0x3f3f3f
using namespace std;
int pre[1050];
int find(int x)
{
int r=x;
while(pre[r]!=r)//r的上一级不是r,说明r不是根结点
r=pre[r];//将其上一级赋给r,继续找
int i=x,j;
while(i!=r)
{
j=pre[i];//将其原本的上一级存起来
pre[i]=r;//将i的上一级置为根节点
i=j;//将i原本的上一级的值赋值给i
}
return r;
}
int union_l(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)//根节点不同
{
pre[fy]=fx;//将fy的上一级置为fx
return 1;
}
return 0;
}
int main()
{
int n,m,i,t,p1,p2;
while(scanf("%d",&n)==1)
{
if(n==0)
break;
//刚开始的时候,有n个城镇,一条路都没有
//那么要修n-1条路才能把它们连起来
t=n-1;
for(i=1;i<=n;i++)
{
pre[i]=i;
}
scanf("%d",&m);
while(m--)//共有m条路
{
scanf("%d%d",&p1,&p2);
if(union_l(p1,p2))
{
t--;
}
}
printf("%d\n",t);
}
return 0;
}