【BZOJ】4668 冷战

Description

被省略的一大坨题目无关信息=w=

一开始这些军工厂之间是不存在铁路的

现在总共有 M 个操作,操作分为两类:

0 u v,这次操作苏联会修建一条连接 u 号军工厂及 v 号军工厂的铁
路,注意铁路都是双向的;
1 u v Reddington 需要知道 u 号军工厂及 v 号军工厂最早在加入第几条条铁路后会联通,假如到这次操作都没有联通,则输出 0 ;

Input

第一行两个整数 N,M
接下来 M 行,每行为 0 u v 1 u v 的形式。
数据是经过加密的,对于每次加边或询问,真正的 u, v 都等于读入的
u, v 异或上上一次询问的答案。一开始这个值为 0
1N,M500000 ,解密后的 u , v 满足 1u,vN , u 不等于v

Output

对于每次 1 操作,输出 u,v 最早在加入哪条边后会联通,若到这个操
作时还没联通,则输出 0

Solution

很明显,连通性的判断要用并查集,但是这个路径带有时间,不支持压缩
那么只能按秩合并(即按size)

然后……就没有然后了=w=

#include<stdio.h>
#include<algorithm>
#define N 500001

using namespace std;

int t,tot,n,m,f[N],s[N],c[N],ans[N],u,v,la,C,T[N];

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) s[i]=1;
    while (m--)
    {
        scanf("%d%d%d",&C,&u,&v);u^=la,v^=la;
        if (C)
        {
            t++;ans[u]=c[u];ans[v]=c[v];bool flag=1;
            for (int lu=0;u;lu=u,u=f[u]) ans[u]=max(c[lu],ans[lu]),T[u]=t;
            for (int lv=0;v;lv=v,v=f[v]) if (T[v]==t)
            {
                printf("%d\n",la=max(ans[v],max(c[lv],ans[lv])));
                flag=0;break;
            }
            else ans[v]=max(c[lv],ans[lv]);
            if (flag) printf("%d\n",la=0);
        }
        else
        {
            tot++;
            while (f[u]) u=f[u];
            while (f[v]) v=f[v];
            if (u==v) continue;
            if (s[u]<s[v]) u^=v^=u^=v;
            s[u]+=s[v];f[v]=u;c[v]=tot;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值