uva 11987 Almost Union-Find

来源:互联网 发布:java实现多张图片上传 编辑:程序博客网 时间:2024/06/03 22:33

I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something similar, but not identical. The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:
1 p q Union the sets containing p and q. If p and q are already in the same set, ignore this command. 2 p q Move p to the set containing q. If p and q are already in the same set, ignore this command. 3 p Return the number of elements and the sum of elements in the set containing p.
Initially, the collection contains n sets: {1}, {2}, {3}, ..., {n}.
Input
There are several test cases. Each test case begins with a line containing two integers n and m (1 ≤ n,m ≤ 100,000), the number of integers, and the number of commands. Each of the next m lines contains a command. For every operation, 1 ≤ p,q ≤ n. The input is terminated by end-of-file (EOF).
Output
For each type-3 command, output 2 integers: the number of elements and the sum of elements.
Explanation Initially: {1}, {2}, {3}, {4}, {5} Collection after operation 1 1 2: {1,2}, {3}, {4}, {5} Collection after operation 2 3 4: {1,2}, {3,4}, {5} (we omit the empty set that is produced when taking out 3 from {3}) Collection after operation 1 3 5: {1,2}, {3,4,5} Collection after operation 2 4 1: {1,2,4}, {3,5}
Sample Input
5 7 1 1 2 2 3 4 1 3 5 3 4 2 4 1 3 4 3 3
Sample Output
3 12 3 7 2 8

点击打开链接

题意:

初始时,一共有n个元素的组合1,2,3....n

给出三个操作

1 p q:合并p,q所在的集合

2 p q:把p移动到q所在的集合

3 p:输出p所在的集合的元素的个数,集合元素的总和;

思路:带权并查集;

#include<stdio.h>int pre[200000+10],a[200000+10],b[200000+10];int find(int x){int r=x;while(r!=pre[r])r=pre[r];int i=x,j;while(i!=r){j=pre[i];pre[i]=r;i=j;}return r;}int main(){int m,n,i,k,p1,p2,p;while(scanf("%d %d",&n,&m)!=EOF){for(i=0;i<=n;i++) {pre[i]=pre[i+n]=i+n;a[i]=a[i+n]=1;b[i]=b[i+n]=i;}while(m--){scanf("%d",&k);if(k==1){scanf("%d %d",&p1,&p2);int fx=find(p1);int fy=find(p2);if(fx!=fy){pre[fx]=fy;a[fy]+=a[fx];b[fy]+=b[fx];}}else if(k==2){scanf("%d %d",&p1,&p2);int fx=find(p1);int fy=find(p2);if(fx!=fy){pre[p1]=fy;a[fy]++;a[fx]--;b[fy]+=p1;b[fx]-=p1;}}else if(k==3){scanf("%d",&p);printf("%d %d\n",a[find(p)],b[find(p)]);}}}return 0;}



0 0
原创粉丝点击