bzoj 4668 冷战——并查集结构

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4668

不路径压缩,维护并查集的树的结构,查询链上最大值。按秩合并就可以暴爬。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e5+5;
int n,m,fa[N],w[N],siz[N],tot,ans;
int rdn()
{
    int ret=0;bool fx=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
    while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
    return fx?ret:-ret;
}
int find(int a)
{
    if(fa[a]==a) return a;
    int f=find(fa[a]);
    return f;
}
void merge(int u,int v)
{
    ++tot;//写在return前! 
    if(u==v) return;//
    if(siz[u]<siz[v]) swap(u,v);
    fa[v]=u; siz[u]+=siz[v];
    w[v]=tot;
}
void query(int u,int v)
{
    int cr=u,d1=0,d2=0,f1,f2;
    while(fa[cr]!=cr)d1++,cr=fa[cr]; f1=cr;
    cr=v; while(fa[cr]!=cr)d2++,cr=fa[cr]; f2=cr;
    if(f1!=f2){puts("0");ans=0;return;}
    if(d1>d2) swap(u,v),swap(d1,d2);
    ans=0;
    while(d2>d1)
        ans=max(ans,w[v]),v=fa[v],d2--;
    while(u!=v)
        ans=max(ans,max(w[u],w[v])),
        u=fa[u],v=fa[v];
    printf("%d\n",ans);
}
int main()
{
    n=rdn(); m=rdn();
    for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
    for(int i=1,op,u,v;i<=m;i++)
    {
        op=rdn(); u=rdn()^ans; v=rdn()^ans;
        if(!op) merge(find(u),find(v));
        else query(u,v);
    }
    return 0;
}

 

posted on 2018-10-06 22:56  Narh  阅读(109)  评论(0编辑  收藏  举报

导航