bzoj 4668 冷战 —— 并查集按秩合并

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=5e5+5;
int n,m,fa[xn],t[xn],dep[xn],siz[xn],ans,cnt;
int rd()
{
int ret=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
return f?ret:-ret;
}
int find(int x)
{
if(fa[x]==x)return x;
int f=find(fa[x]);
dep[x]=dep[fa[x]]+1;
return f;
}
void merge(int x,int y,int tim)
{
int u=find(x),v=find(y);
if(u==v)return;
if(siz[u]<siz[v])swap(u,v);
fa[v]=u; siz[u]+=siz[v]; t[v]=tim;
}
int query(int x,int y)
{
int u=find(x),v=find(y);
if(u!=v)return 0;
int ret=0;
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])ret=max(ret,t[x]),x=fa[x];
while(x!=y)ret=max(ret,max(t[x],t[y])),x=fa[x],y=fa[y];
return ret;
}
int main()
{
n=rd(); m=rd();
for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;
for(int i=1,p,u,v;i<=m;i++)
{
p=rd(); u=rd(); v=rd();
u^=ans; v^=ans;
if(!p)merge(u,v,++cnt);
else printf("%d\n",ans=query(u,v));
}
return 0;
}

posted @ 2018-10-06 22:50  Zinn  阅读(104)  评论(0编辑  收藏  举报