uva 11987 Almost Union-Find (并查集删点,转移)

来源:互联网 发布:慕尼黑工业大学 知乎 编辑:程序博客网 时间:2024/06/06 02:54

解题思路:并不真实删除那个节点,而是每次新建一个节点添加到另一个集合之中去。

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~4294967295int   2147483648~2147483647unsigned long 0~4294967295long   2147483648~2147483647long long的最大值:9223372036854775807long long的最小值:-9223372036854775808unsigned long long的最大值:18446744073709551615__int64的最大值:9223372036854775807__int64的最小值:-9223372036854775808unsigned __int64的最大值:18446744073709551615*/


原创粉丝点击