BZOJ1854 [Scoi2010]游戏

题意:中文题,懒得写题意

分析:

神题,神做法。

想了半天不会,只能无耻地搜题解了。

这道题是用并查集来做。

将武器看成边,连接两个属性值,如果一个连通块是一颗树,那么肯定有一个属性值不能得到,如果一个x个点的连通块边数>=x,说明这个连通块里所有属性值都能得到。

涉及到连通块,我们可以用并查集来维护。

如果当前武器的两个属性值不在一个集合,我们就将属性值小的所在的集合合并到属性值大的所在的集合,这样,如果一个连通块是一棵树,肯定是树根不能得到。

#include <cstdio>
#include <algorithm>

int n,x,y,f[10005],vis[10005];
int fnd(int x) {return f[x] == x ? x : f[x] = fnd(f[x]);}

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= 10000; i++) f[i] = i;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d", &x, &y);
		int u = fnd(x), v = fnd(y);
		if(u != v) {
			if(u > v) std::swap(u, v);
			f[u] = v, vis[u] = 1;
		} else vis[u] = 1;
	}
	for(int i = 1; i <= 10001; i++) if(!vis[i]) {printf("%d", i-1); return 0;}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值