解题思路:并不真实删除那个节点,而是每次新建一个节点添加到另一个集合之中去。
AC代码:
/*
@Author: wchhlbt
@Date: 2017/7/27
*/
#include <bits/stdc++.h>
#define Fori(x) for(int i=0;i<x;i++)
#define Forj(x) for(int j=0;j<x;j++)
#define maxn 300000
#define inf 0x3f3f3f3f
#define ONES(x) __builtin_popcount(x)
#define pb push_back
#define _ << " " <<
using namespace std;
typedef long long ll ;
const double eps =1e-8;
const int mod = 1000000007;
typedef pair<int, int> P;
const double PI = acos(-1.0);
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int n,m;
int fa[maxn];
int id[maxn];
ll sum[maxn];//维护总和
int num[maxn];//维护总数
int cnt;
void init()
{
cnt = n;
for(int i = 1; i<=n; i++)
fa[i] = i,sum[i] = i,num[i] = 1, id[i] = i;
}
//connect & find 调用的时候需要使用id值
int find(int u)
{
return (fa[u]==u) ? u : (fa[u] = find(fa[u]));
}
bool connect(int u, int v)//false 表明两个元素已经位于一个集合之中
{
int fu = find(u);
int fv = find(v);
if(fu!=fv){
fa[fu] = fv;
sum[fv] += sum[fu];
num[fv] += num[fu];
return true;
}
return false;
}
void mov(int u, int v)
{
int fu = find(id[u]);
int fv = find(id[v]);
if(fu==fv) return;
id[u] = ++cnt;
num[cnt] = 1;
sum[cnt] = u;
fa[cnt] = cnt;
connect(cnt,id[v]);
//del
sum[fu] -= u;
num[fu]--;
}
int main()
{
//freopen("test.txt","r",stdin);
while(cin>>n>>m)
{
init();
while(m--){
int type,u,v;
cin>>type;
if(type==1){
scanf("%d%d",&u,&v);
connect(id[u],id[v]);
}
else if(type==2){
scanf("%d%d",&u,&v);
mov(u,v);
}
else{
scanf("%d",&u);
int fu = find(id[u]);
cout << num[fu] << " " << sum[fu] << endl;
}
}
}
return 0;
}
/*
unsigned int 0~4294967295
int 2147483648~2147483647
unsigned long 0~4294967295
long 2147483648~2147483647
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:18446744073709551615
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
*/