UVA 11987 Almost Union-Find (并查集,可持久化)

大白书:p246 UVA 11987Almost Union-Find

加一个id[],不修改,而是insert,然后改id

const int MAXN = 100010 * 2;
const int MOD = 1000000;
 
int fa[MAXN], num[MAXN];
int sum[MAXN];
 
int idx[MAXN];
 
void init(int n)
{
   REP(i, n + 1)
    {
       idx[i] = i;
       fa[i] = i;
       num[i] = 1;
       sum[i] = i;
    }
}
 
int find(int x)
{
   if (x != fa[x])
       fa[x] = find(fa[x]);
   return fa[x];
}
 
int main()
{
   int n, m;
   int x, y;
   while (cin >> n >> m)
    {
       init(n);
       int k = n + 1;///!!!!!!
       while (m--)
       {
           RI(x);
           if (x == 1)
           {
                RII(x, y);
                int xx = idx[x];
                int yy = idx[y];
                int fax = find(xx);
                int fay = find(yy);
                if (fax != fay)
                {
                    fa[fax] = fay;
                    num[fay] += num[fax];
                    sum[fay] += sum[fax];
                }
           }
           else if (x == 2)
           {
                RII(x, y);
                int xx = idx[x];
                int yy = idx[y];
                int fax = find(xx);
                int fay = find(yy);
                if (fax != fay)
                {
                    num[fax]--;
                    sum[fax] -= x;
                    num[fay]++;
                    sum[fay] += x;
 
                    idx[x] = k;
                    num[k] = 1;
                    sum[k] = x;
                    fa[k] = fay;
                    k++;
                }
           }
           else
           {
                RI(x);
                int xx = idx[x];
                int fax = find(xx);
                printf("%d %d\n",num[fax], sum[fax]);
           }
       }
//       FE(i, 1, n)
//       {
//            int fax = find(idx[i]);
//            cout << i << "" << idx[i] << " " << fax << "" << num[fax] << " " << sum[fax] <<endl;
//       }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值