2 5 3 1 2 2 3 4 5 5 1 2 5
2 4
题目大意:
有N个男孩在一个房间里面,这个叫XX的人指定其中几个人为好朋友,好朋友能相互传递,比如说A和B是好朋友,AC也是好朋友,那么BC就是好朋友。求,最长的那一堆好朋友有几个人
遇到的问题和解决思路:
首先就是并查集问题。这里可以运用树根是多少,把所有的人都排到一个人上面去就可以了。当然rank不能设置成0,如果设置能0,那么不管怎么加都是0。然后设置成1的原理就是,因为每个人刚开始就是一个单位,所以刚开始的根就是1.
还有就是n可能是0,也就是没有一个人拥有朋友。
给出代码:
这里的原则是,把所有的根上的值都加到顶端上去。单纯的利用par[x] = y; rank[y] += rank[x]
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int MAX_N = 100000 + 20; const int MAX_R = 10000000 + 50; int par[MAX_R], rank1[MAX_R]; int n, high, a, b; void init(){ for(int i = 1; i <= MAX_R - 30; i++){ par[i] = i; rank1[i] = 1;//rank一定要是1 } } int find(int x){ if(par[x] == x)return x; return par[x] = find(par[x]); } bool same(int x, int y){ return find(x) == find(y); } void unite(int x, int y){ x = find(x); y = find(y); if(x == y) return ; par[x] = y; rank1[y] += rank1[x]; } int main(){ while(scanf("%d", &n) != EOF){ if(n == 0){ printf("%d\n", 1); continue; } init(); high = 0; for(int i = 1; i <= n; i++){ scanf("%d%d", &a, &b); if(!same(a, b)){ unite(a, b); high = max(high, max(rank1[find(a)], rank1[find(b)]));//寻找最大的 } } printf("%d\n", high); } return 0; }
后来我又思考了一下,把小的当成根,把大的当做末尾,然后每一次就是+1,但是因为刚开始少加了1,所以最后输出high+1.
给出代码(就只有unite和printf这里有不同):
这里的是,把所有的值放到末尾上去。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int MAX_N = 100000 + 20; const int MAX_R = 10000000 + 50; int par[MAX_R], rank1[MAX_R]; int n, high, a, b; void init(){ for(int i = 1; i <= MAX_R - 30; i++){ par[i] = i; rank1[i] = 0; } } int find(int x){ if(par[x] == x)return x; return par[x] = find(par[x]); } bool same(int x, int y){ return find(x) == find(y); } void unite(int x, int y){ x = find(x); y = find(y); if(x == y) return ; if(x > y){ par[y] = x; rank1[x] = rank1[x] + rank1[y] + 1; } else { par[x] = y; rank1[y] = rank1[x] + rank1[y] + 1; } } int main(){ while(scanf("%d", &n) != EOF){ if(n == 0){ printf("%d\n", 1); continue; } init(); high = 0; for(int i = 1; i <= n; i++){ scanf("%d%d", &a, &b); if(!same(a, b)){ unite(a, b); high = max(high, max(rank1[find(a)], rank1[find(b)])); } } printf("%d\n", high + 1); } return 0; }