bzoj 4668 冷战 —— 并查集按秩合并
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=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; }