CsuOJ 1092(大尾巴狼的朋友)——因为小细节一直在WA...

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1092

这道题要求找出与大尾巴狼的朋友个数,依然是用并查集。我的思路是将父节点数值大的

集合并入数值小的集合,这是为了照顾大尾巴狼的编号1,然后就有两种做法了。其实也差

不多,第一种是定义一个数组cnt来存放集合元素的个数,然后在合并集合的过程中不断更

新cnt的值,最后输出cnt[1] -1;另一种做法是先将集合合并,最后从2开始循环找一遍

p[x]=1的元素的个数输出。

第一种的代码:

 

 1 #include<iostream>
2 #define N 10000005
3 using namespace std;
4
5 int p[N],cnt[N];
6 int find_set(int x)
7 {
8 return p[x] == x ? x : (p[x] = find_set(p[x]));
9 }
10
11 void union_set(int x, int y)
12 {
13 x = find_set(x);
14 y = find_set(y);
15 if(x == y) return;
16 else if(x < y){
17 p[y] = x;
18 cnt[x] += cnt[y];
19 }
20 else if(x > y){
21 p[x] = y;
22 cnt[y] += cnt[x];
23 }
24 }
25
26 int main()
27 {
28 int n,m;
29 int a,b;
30 while(scanf("%d%d", &n, &m)!=EOF)
31 {
32 for(int i = 0; i <= m; i++) {
33 p[i] = i;
34 cnt[i] = 1;
35 }
36 for(int i = 0; i < n; i++)
37 {
38 scanf("%d%d", &a, &b);
39 union_set(a,b);
40 }
41 printf("%d\n",cnt[1] - 1);
42 }
43 return 0;
44 }



第二种的代码(这种貌似空间复杂度低一些):

 

#include<iostream>
#define N 10000005
using namespace std;

int p[N];
int find_set(int x)
{
return p[x] == x ? x : (p[x] = find_set(p[x]));
}

void union_set(int x, int y)
{
x = find_set(x);
y = find_set(y);
if(x == y) return;
else if(x < y){
p[y] = x;
}
else if(x > y){
p[x] = y;
}
}

int main()
{
int n,m;
int a,b;
while(scanf("%d%d", &n, &m)!=EOF)
{
for(int i = 0; i <= m; i++) {
p[i] = i;
}
for(int i = 0; i < n; i++)
{
scanf("%d%d", &a, &b);
union_set(a,b);
}
int cnt = 0;
for(int i = 2 ; i <= m; i++)
if(p[i] == 1) cnt++;
printf("%d\n",cnt);
}
return 0;
}


在做的过程中因为不细心将 return p[x] == x ? x : (p[x] = find_set(p[x]));

写成了 return p[x] == x ? x : (p[x] == find_set(p[x]));WA了5次,必须注意

细节啊。。。

 

你可能感兴趣的:(wa)