省选专练CF1027F Session in BSU

版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/81866047

如果你做过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;
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81866047