省选专练CF1027F Session in BSU

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值