并查集小拓展

估计要明晚才写得完,于是暂时持续更新。

所谓拓展,肯定和简单地用并查集去维护联通性不同。

较为简单的联通性问题如: http://blog.csdn.net/z635457712a/article/details/7919198

1. 维护一种相对的信息,用不规范的说法就是带权值的并查集

Lyp 的战斗记录
众所周知,我们的 lyp 神犇外号叫 Altman,的确,在另一个平行宇宙,lyp神犇就是一个——Altman。
有一天,lyp 神犇遇到了另一个平行宇宙中的他,得知了在其他的宇宙中,Altman 是存在的,那么,怪兽也是存在的咯。
作为一个有名的 oier,lyp 神犇想要统计一下各个宇宙中怪兽的战斗力,他发现,一些怪兽在不同的宇宙都出现过(!. !,难不成怪兽不穿越,算了,不管了),每一个 Altman 都提供给 lyp 一些信息,告诉他一个怪兽比另一个怪兽的战斗力大多少(这个数可以是负数)。Altman 神犇为了给你以表现机会,将这些信息都给你,并会时不时地问你两个怪兽之间谁更强。假设 Altman 们提到了怪兽都按 1~n 编号。
Altman 们的信息的格式是 X  A  B  C
其中 x 固定为 1,A,B 是两个 1~n 的整数,表示怪兽编号,A 怪兽的战斗力比 B 怪兽的战斗力大 C(C 为整数),保证信息之间不矛盾。

Lyp 的询问的格式是:Y  A  B 
Y 固定为 2,A,B 是怪兽编号,属于 1~n,如果 A 比 B 强,输出 A;如果 B比 A 强,输出 B,如果无法判断或怪兽们一样强,输出 0

【输入格式】: 第 1 行,两个数 n,q,n 表示怪兽总数,q 表示询问与信息的总数;
第 2~q+1 行, 每一行是一个信息或询问,格式如题;
【输出格式】: 对于每一个询问,用单独一行回答。
【样例】:
Input
3  3
1  1  2  3
1  3  2  1
2  1  3

Output
1

【数据约定】:  30%   n<=100  q<=300
100%  n<=30000  q<=50000
c 的绝对值不超过 5000

这类题有种类似向量加法的感觉,一直A -> B, B -> C, 就可以推知A -> C。

code

#include <cstdio>
#include <iostream>
using namespace std;
const int maxn = 30000 + 5;

//class union_find_set
typedef int INT[maxn];
int n, q;
INT w, ufs;

int find(int u)
{
   if (u != ufs[u])
   {
      int f = find(ufs[u]);
      w[u] += w[ufs[u]];
      ufs[u] = f;
   }
   return ufs[u];
}

int main()
{
   freopen("lyp.in", "r", stdin);
   freopen("lyp.out", "w", stdout);

   cin >> n >> q;
   for (; n; --n) ufs[n] = n;
   for (; q; --q)
   {
      int ch;
      scanf("%d", &ch);
      switch (ch)
      {
         int x, y, z, fi, fj;
         case 1 :
            scanf("%d%d%d", &x, &y, &z);
            fi = find(x), fj = find(y);
            w[fi] = z - (w[x] - w[y]);
            ufs[fi] = fj;
            break; 
         case 2 :
            scanf("%d%d", &x, &y);
            fi = find(x), fj = find(y);
            if (fi != fj) cout << "0" << endl;
            else if (w[x] > w[y]) cout << x << endl;
            else if (w[x] < w[y]) cout << y << endl;
            else if (w[x] == w[y]) cout << "0" << endl;
            break;
      }
   }

   return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值