【题解】CF1027F:Session in BSU

本文介绍了一种使用并查集数据结构解决特定时间选择问题的方法。通过离散化和并查集的连边操作,实现了对多个任务中时间的选择与调整,确保了每个任务至少选择一个时间点,避免重复选择同一时间点。文章提供了详细的代码实现,展示了并查集在处理此类问题上的高效性和灵活性。

原题传送门
这题我用并查集过了
看到范围1e9,所以先离散
然后每次把点对应的两个时间用并查集连条边
对于每个点的两个时间,分类讨论

  • 两个时间都没选,暂时选小的那个,并用并查集把两个时间连起来
  • 有一个选了,那么这次选剩下的那个,然后把这两个时间删掉(就是在并查集里把他们的祖先设置为0)
  • 都选过了(表现为两个时间的祖先都为0),那么直接输出-1得了

为什么这题用并查集就搞定了呢,并查集的连边操作的意义是什么?
其实感性理解一下就行了
( 1 , 5 ) ( 1 , 7 ) ( 5 , 13 ) (1,5)(1,7)(5,13) (1,5)(1,7)(5,13)为例
对于第一个任务,我先选了1,把1与5连起来,并且5是1的祖先;
对于第二个任务,我的待选时间就变为了 ( 5 , 7 ) (5,7) (5,7),那么我选5的意义是:对于第一个任务选1的操作反悔,改选5,然后我在第二个任务的时候选择了1
这就是并查集在这里的用处
具体实现在代码更好

Code:

#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;
struct node{
	int id, x, v;
}a[maxn << 1];
int n, ans, num[maxn << 1], f[maxn << 1], p;

inline int read(){
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

bool cmp1(node x, node y){ return x.x < y.x; }
bool cmp2(node x, node y){ return x.id == y.id ? x.v < y.v : x.id < y.id; }
int get(int k){ return k == f[k] ? k : f[k] = get(f[k]); }

int main(){
	n = read();
	for (int i = 1; i <= n; ++i) a[(i << 1) - 1].x = read(), a[i << 1].x = read(), a[(i << 1) - 1].id = a[i << 1].id = i;
	sort(a + 1, a + 1 + (n << 1), cmp1);
	a[0].x = a[1].x + 1;
	for (int i = 1; i <= (n << 1); ++i) a[i].v = a[i].x == a[i - 1].x ? p : ++p, num[a[i].v] = a[i].x;
	sort(a + 1, a + 1 + (n << 1), cmp2);
	for (int i = 1; i <= p; ++i) f[i] = i;
	for (int i = 1; i <= n; ++i){
		int s1 = get(a[(i << 1) - 1].v), s2 = get(a[i << 1].v);
		if (!s1 && !s2){ puts("-1"); return 0; }
		if (s1 == s2 || !s1 || !s2){ ans = max(ans, max(num[s1], num[s2])); f[s1] = f[s2] = 0; } else{
			if (s1 > s2) swap(s1, s2);
			ans = max(ans, num[s1]); f[s1] = s2;
		}
	}
	printf("%d\n", ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值