传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1854

没想到怎么做真是不应该,看到每个武器都有两个属性,应该要想到连边构图的!太不应该了!

构图之后,显然,一个有n个点的联通块要么有n - 1条边,要么有>=n条边(因为可能有重边)。由于一把武器只能使用一次,也就是说一条边只能“属于”其连接的两个点的其中一个。当有n - 1条边时,这时一棵树,这棵树里的边可以满足任意的n - 1个点,因为随便找一个点拉成有根树,使每一条边都“属于”其儿子节点就行了。那么这种情况是不是真的要“随便找一个点”呢?实则不然。因为题目要求了,要按照顺序打boss,所以应该尽量让编号更小的点得到一条边,所以应该让编号最大的点成为树根,对应程序里,在并查集union操作时,应该让编号较小的成为编号较大的儿子,然后标记编号较小的节点。当有>= n条边时,很显然所有点都可以得到一条边,岂不美哉?对应程序里,此时getfa找到的两个fa是一样的,那么就标记这个fa。

#include <cstdio>

const int maxn = 1000005;

int n, u, v, fu, fv, fa[10005], tem;
char ch, ok[10005]; int getfa(int aa) {
return aa == fa[aa]? aa: fa[aa] = getfa(fa[aa]);
}
inline void readint(int & rt) {
while ((ch = getchar()) < 48);
rt = ch - 48;
while ((ch = getchar()) > 47) {
rt = rt * 10 + ch - 48;
}
} int main(void) {
//freopen("in.txt", "r", stdin);
readint(n);
for (int i = 1; i < 10001; ++i) {
fa[i] = i;
}
for (int i = 0; i < n; ++i) {
readint(u);
readint(v);
fu = getfa(u);
fv = getfa(v);
if (fu == fv) {
ok[fu] = 1;
}
else {
if (fu < fv) {
tem = fu;
fu = fv;
fv = tem;
}
fa[fv] = fu;
ok[fv] = 1;
}
}
int i;
for (i = 1; ok[i]; ++i);
printf("%d\n", i - 1);
return 0;
}

  

最新文章

  1. 5-2 bash 脚本编程之一 变量、变量类型等
  2. 【模式匹配】更快的Boyer-Moore算法
  3. 二、Spring——AoP
  4. 转 自定义View之onMeasure()
  5. 带百分号的数据转json
  6. 基于Web的数据推送技术(转)
  7. js中的继承1--类继承
  8. POJ 3061 Subsequence 二分查找
  9. Java Proxy和CGLIB动态代理原理
  10. .NET开发中基础问题,CODE First AND DB First(大牛自动忽略,小白可以看一下)
  11. Mysql语句中当前时间不能直接使用C#中的Date.Now传输
  12. with文件操作
  13. 最全的测试用例(UI)
  14. vue教程1-05 事件 简写、事件对象、冒泡、默认行为、键盘事件
  15. POJ 2965&amp;&amp;1753
  16. show point on image
  17. .Net Actor 服务端开发框架,Newbe.Claptrap 项目周报 1 - 还没轮影,先用轮跑
  18. HDU 6214 Smallest Minimum Cut 最小割,权值编码
  19. TCP的建立和终止 图解
  20. 【LeetCode】128. Longest Consecutive Sequence

热门文章

  1. C、C++混合编程之extern &quot;C&quot;
  2. iconfont的图文混排
  3. string interpolation in sql server
  4. How to create a List of ValueTuple?
  5. g00 网站说明
  6. sql注入原理与实践
  7. codeforces 690D2 D2. The Wall (medium)(组合数学)
  8. 前端CSS规范整理
  9. GCD基础知识
  10. 【NOIP2016】 组合数问题