思路:
并查集的基本运用,并不需要什么优化就行的。
推荐一篇我觉得讲并查集讲的很有意思的文章:http://blog.csdn.net/dellaserss/article/details/7724401
ps:第一份代码没有路径压缩。。。然而还是31ms过。。
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int node[1100];
int _find(int x){//并
while(node[x] != x){
x = node[x];
}
return x;
}
void _merge(int x,int y){//查
int xx = _find(x);
int yy = _find(y);
if(xx != yy)
node[yy] = xx;
}
int main()
{
int n,m;
int xx,yy;
while(scanf("%d",&n),n){
scanf("%d",&m);
for(int i = 1;i <= 1000;i++){
node[i] = i;
}
for(int i = 1;i <= m;i++){
scanf("%d%d",&xx,&yy);
_merge(xx,yy);
}
int res = 0;
for(int i = 1;i <= n;i++){
if(node[i] == i)
res++;
}
printf("%d\n",res-1);
}
return 0;
}
AC代码:
这个带来路径压缩,然而还是31ms。。。只能说这题没卡这里吧
#include <iostream>
#include <cstdio>
using namespace std;
int node[1100];
int _find(int x){
int xx = x;
while(node[xx] != xx){
xx = node[xx];
}
int temp;
while(x != xx){
temp = node[x];
node[x] = xx;
x = temp;
}
return xx;
}
void _merge(int x,int y){
int xx = _find(x);
int yy = _find(y);
if(xx != yy)
node[yy] = xx;
}
int main()
{
int n,m;
int xx,yy;
while(scanf("%d",&n),n){
scanf("%d",&m);
for(int i = 1;i <= 1000;i++){
node[i] = i;
}
for(int i = 1;i <= m;i++){
scanf("%d%d",&xx,&yy);
_merge(xx,yy);
}
int res = 0;
for(int i = 1;i <= n;i++){
if(node[i] == i)
res++;
}
printf("%d\n",res-1);
}
return 0;
}