简单并查集
来源:互联网 发布:大数据产生的背影 题 编辑:程序博客网 时间:2024/04/20 14:57
Description
Problem A
Almost Union-Find
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). The size of input file does not exceed 5MB.
Output
For each type-3 command, output 2 integers: the number of elements and the sum of elements.
Sample Input
5 71 1 22 3 41 3 53 42 4 13 43 3
Output for the Sample Input
3 123 72 8
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}
题意:给你三种操作,合并,删点,查询该点所在的集合中元素的个数和所有元素的和
思路:刚开始做,考虑到当删除根节点时,将根节点指向root++,然后再将根节点的孩子指向root
例如:本来1,3 ,4在一个集合(集合最大值为4)现在你想执行2 4 2这个操作,那么你应把4节点删除然后rank[]和sum[]向应的减少,鼓捣了半天竟然超时。 想了想,在建立一个far1【】对根进行操作。思路还是上面的思路,只是当转移的时候,将far1[]中对应的值和你想要删除的点和另一个点重新建立关系,那么原来的那个节点就成了虚点。
#include<iostream>
#include<algorithm>
#include<cstdio>
#define max 100100*2
using namespace std;
int m,n;
int far[max];
int far1[max];
int sum[max];
int rank[max];
int root;
int c,a,b;
void init(int x)
{
for(int i=1; i<=x; i++)
{
far[i]=i;
far1[i]=i;
rank[i]=1;
sum[i]=i;
}
}
int find_set(int n)
{
int tem;
if(n==far[n])
return n;
far[n]=find_set(far[n]);
return far[n];
}
void Union_set1(int a,int b)
{
int x=find_set(far1[a]);
int y=find_set(far1[b]);
if(x==y)
return ;
sum[y]+=sum[x];
far[x]=y;
rank[y]+=rank[x];
}
void Union_set2(int a,int b)
{
int x=find_set(far1[a]);
int y=find_set(far1[b]);
if(x==y)
return ;
int xx=far1[a];
rank[find_set(xx)]--;
sum[find_set(xx)]-=a;
far1[a]=root++;
sum[far1[a]]=a;
rank[far1[a]]=1;
far[far1[a]]=far1[a];
Union_set1(a,b);
}
int main()
{
int ans1,ans2;
int tem;
while(scanf("%d%d",&m,&n)!=EOF)
{
root=m+1;
init(m);
while(n--)
{
scanf("%d",&c);
switch(c)
{
case 1:
scanf("%d%d",&a,&b);
Union_set1(a,b);
break;
case 2:
scanf("%d%d",&a,&b);
Union_set2(a,b);
break;
case 3:
scanf("%d",&a);
tem=find_set(far1[a]);
printf("%d %d\n",rank[tem],sum[tem]);
break;
}
}
}
return 0;
}
- 简单并查集
- 简单并查集
- 简单并查集
- 简单并查集
- 简单并查集
- 简单并查集
- 并查集简单应用
- zoj1789-简单并查集
- zoj2740-简单并查集
- 并查集简单模板
- poj1611(简单并查集)
- 并查集简单应用
- 简单并查集小结。
- POJ2524(简单并查集)
- hdu2545(简单并查集)
- poj1611 简单并查集
- 并查集简单题
- 并查集简单实现
- Struts2中Session的使用
- XMPP——Smack[1]连接、登陆及账户操作
- c语言 socket编程
- Java模拟单向链表和双向链表的实现
- OpenGL ES --Flat coloring和Smooth coloring
- 简单并查集
- chmod & chown
- js零碎知识点
- Boost.Lambda
- java实现二叉树的常见操作
- JIT File description
- Xceed Datagrid for Wpf中带有可编辑combox项做法实例
- quartz定时器格式设置
- Orcal中的SQL语句