Lyp的战斗记录

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 行, 每一行是一个信息或询问,格式如题;


输出格式

对于每一个询问,用单独一行回答。


样例输入

3 3
1 1 2 3
1 3 2 1
2 1 3


1


数据约定

30% n<=100 q<=300
100% n<=30000 q<=50000 c 的绝对值不超过 5000


Solution

带权并查集。


Code

#include <iostream>
#include <cstdio>
#include <assert.h>

using namespace std;

int n,q;
int fa[30010][3];

int find(int x){
    if(x==fa[x][0])return x;
    int tmp=find(fa[x][0]);
    fa[x][1]+=fa[fa[x][0]][1];
    fa[x][0]=tmp;
    return tmp;
}

int main(){

#ifndef DEBUG
    freopen("lyp.in","r",stdin);
    freopen("lyp.out","w",stdout);
#endif

    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        fa[i][0]=i;
        fa[i][1]=0;
    }
    for(int i=1,ss;i<=q;i++){
        int x,y,z;
        scanf("%d%d%d",&ss,&x,&y);
        if(ss==1){
            scanf("%d",&z);
            int fy=find(y);
            fa[fy][0]=x;
            fa[fy][1]=z-fa[y][1];
        }
        else{
            int fx=find(x),fy=find(y);
            if(fx!=fy){
                printf("0\n");
                continue;
            }
            else{
                if(fy==y){
                    if(fa[x][1]>0)printf("%d\n",y);
                    else if(fa[x][1]<0)printf("%d\n",x);
                    else printf("0\n");
                    continue;
                }
                if(fx==x){
                    if(fa[y][1]>0)printf("%d\n",x);
                    else if(fa[y][1]<0)printf("%d\n",y);
                    else printf("0\n");
                    continue;
                }
                if(fa[x][1]>0&&fa[y][1]<0)printf("%d\n",y);
                else if(fa[x][1]<0&&fa[y][1]>0)printf("%d\n",x);
                else if(fa[x][1]<fa[y][1])printf("%d\n",x);
                else if(fa[x][1]>fa[y][1])printf("%d\n",y);
                else printf("0\n");
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值