如果你做过SCOI2010连续攻击游戏
就会一眼发现做法——并查集维护二分图
这个做法:
并查集要特意把祖先放的较大
这样祖先就是这个联通块的最大权
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=1e6+10000;
struct Node{
int x,y;
}A[N];
int mmp[N*2]={};
int f[N]={};
int n;
int cnt=0;
int getfa(int x){
if(f[x]==x)return x;
else return f[x]=getfa(f[x]);
}
int main(){
read(n);
for(int i=1;i<=n;i++){
read(A[i].x);
read(A[i].y);
cnt++;
mmp[cnt]=A[i].x;
cnt++;
mmp[cnt]=A[i].y;
}
sort(mmp+1,mmp+1+cnt);
int len=unique(mmp+1,mmp+1+cnt)-mmp-1;
for(int i=1;i<=n;i++){
A[i].x=lower_bound(mmp+1,mmp+1+len,A[i].x)-mmp;
A[i].y=lower_bound(mmp+1,mmp+1+len,A[i].y)-mmp;
}
int ans=0;
for(int i=1;i<=len;i++)f[i]=i;
for(int i=1;i<=n;i++){
int dx=getfa(A[i].x);
int dy=getfa(A[i].y);
if(!dx&&!dy){
cout<<-1;
exit(0);
}
if(dx>dy)swap(dx,dy);
if(dx==dy||!dx||!dy){
ans=max(ans,mmp[dx]);
f[dx]=f[dy]=0;
}
else{
ans=max(ans,mmp[dx]);
f[dx]=dy;
}
}
cout<<ans;
}