bzoj 1854 游戏 二分图匹配 || 并查集
题目链接
Description
lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次?
Input
输入的第一行是一个整数N,表示lxhgww拥有N种装备 接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值
Output
输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。
Sample Input
3
1 2
3 2
4 5
Sample Output
2
HINT
【数据范围】
对于30%的数据,保证N < =1000
对于100%的数据,保证N < =1000000
思路
参考:
http://hzwer.com/2950.html
http://blog.csdn.net/PoPoQQQ/article/details/41544997
法一:二分图最大匹配
思路同bzoj 1911.
将每种武器和它的两种属性连边,因为属性数为\(1e3\),武器数为\(1e6\),故用属性去匹配武器,这也符合属性从小到大连续的要求。
注意点,匈牙利算法中每次都要初始化\(used[]\)数组,在这里代价太高,故可用时间戳代替(一开始将时间戳开成了\(bool\)数组玄学到哭泣)。
法二:并查集
十分巧妙。
将武器的属性抽象成点,考虑在同一种武器的两种属性间连边。
如果一个联通块了呈树形结构,且树中节点为\(x\)个,则能从中取\(x-1\)个武器。
方式是每个点分配给它上面的那条边,这样,除了根节点之外的每个点都能分配到一条边。即这些\(x-1\)个属性都能对应到一个武器。
如果不是树形结构,且其中节点为\(x\)个,则能取\(x\)个武器。
因为不是树,所以其中必然有环。那么,给环上的每个点分配它顺时针方向的一条边,给不在环上的点分配靠近环方向的边。这样,每个点都能分配到一条边。即\(x\)个属性每个都能对应到一个武器。
可以考虑用并查集来做。祖先节点为编号最大的节点,其是否可以被选择不确定,其子孙节点都是可以选择的(详见上面讨论的两种情况)。
考虑在\(x\)和\(y\)之间加边,
如果\(x\)的祖先\(fx\)与\(y\)的祖先\(fy\)相同,则说明加出了环,则祖先节点本身也可被选择;
如果不同,则让两个祖先中较小的那个未被选择的能够被选择。
最后从小到大扫描一遍,不连续即停。
小结
两种不同的建图方式,两种做法,都很有启发意义。
Code
Ver. 1
#include <bits/stdc++.h>
#define maxn 10000
#define maxm 1000010
using namespace std;
typedef long long LL;
struct Edge {
int to, ne;
Edge(int _to=0, int _ne=0) : to(_to), ne(_ne) {}
}edge[maxm * 2];
int tot, ne[maxm], T, match[maxm], vis[maxm];
void add(int u, int v) {
edge[tot] = Edge(v, ne[u]);
ne[u] = tot++;
}
int find(int u) {
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (vis[v] != T) {
vis[v] = T;
if (!match[v] || find(match[v])) {
match[v] = u;
return true;
}
}
}
return false;
}
int main() {
int n;
scanf("%d", &n);
tot = 0; memset(ne, -1, sizeof(ne));
for (int i = 0; i < n; ++i) {
int x, y;
scanf("%d%d", &x, &y);
add(x, i), add(y, i);
}
int i = 1;
for (; i <= maxn; ++i) {
++T;
if (!find(i)) break;
}
printf("%d\n", i-1);
return 0;
}
Ver. 2
#include <bits/stdc++.h>
#define maxn 10000
using namespace std;
typedef long long LL;
bool vis[maxn+10];
int fa[maxn+10];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= maxn; ++i) fa[i] = i;
for (int i = 0; i < n; ++i) {
int x, y;
scanf("%d%d", &x, &y);
x = find(x), y = find(y);
if (x == y) vis[x] = true;
else {
if (x > y) swap(x, y);
if (vis[x]) vis[y] = true;
else vis[x] = true;
fa[x] = y;
}
}
int i=1;
for (; i <= maxn && vis[i]; ++i);
printf("%d\n", i-1);
return 0;
}
bzoj 1854 游戏 二分图匹配 || 并查集的更多相关文章
- BZOJ 1854 游戏(二分图匹配或并查集)
此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个 ...
- HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流
二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...
- BZOJ 1854: [Scoi2010]游戏(二分图匹配/并查集)
题面: https://www.lydsy.com/JudgeOnline/problem.php?id=1854 题解: 1.二分图匹配: 首先我们发现每件装备只能在两种属性中选一种.因此,我们以每 ...
- [BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法 ...
- HDU 3081:Marriage Match II(二分图匹配+并查集)
http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意:有n个男生n个女生,他们只有没有争吵或者女生a与男生A没有争吵,且女生b与女生a是朋友,因此女生b也 ...
- HDU 3081 Marriage Match II (二分图,并查集)
HDU 3081 Marriage Match II (二分图,并查集) Description Presumably, you all have known the question of stab ...
- BZOJ.2054.疯狂的馒头(并查集)
BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...
- noip 2010 关押罪犯 二分答案+二分图染色 || 并查集
题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...
- 2021.08.03 BZOJ 疯狂的馒头(并查集)
2021.08.03 BZOJ 疯狂的馒头(并查集) 疯狂的馒头 - 题目 - 黑暗爆炸OJ (darkbzoj.tk) 重点: 1.并查集的神奇运用 2.离线化 题意: 给一个长为n的序列,进行m次 ...
随机推荐
- 第一次通过CLR Profile解决内存占用过高的问题
炮哥:"嘿,哥们,忙啥呢,电脑卡成这逼样." 勇哥:"在用CLR Profile工具分析下FlexiPrint的内存占用情况." 炮哥:“哎哟,不错啊,玩高级的 ...
- 只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie
只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie
- BZOJ4736 温暖会指引我们前行(LCT+最大生成树)
类似于瓶颈路,满足条件的路径一定在温度的最大生成树上,那么就是一个LCT维护MST的裸题了. #include<iostream> #include<cstdio> #incl ...
- es6常用基础合集
es6常用基础合集 在实际开发中,ES6已经非常普及了.掌握ES6的知识变成了一种必须.尽管我们在使用时仍然需要经过babel编译. ES6彻底改变了前端的编码风格,可以说对于前端的影响非常巨大.值得 ...
- BZOJ3456:城市规划——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3456 求出n个点的简单(无重边无自环)无向连通图数目 模数很熟悉,先敲一个NTT. 然后通过推导式 ...
- HDU.2647 Reward(拓扑排序 TopSort)
HDU.2647 Reward(拓扑排序 TopSort) 题意分析 裸的拓扑排序 详解请移步 算法学习 拓扑排序(TopSort) 这道题有一点变化是要求计算最后的金钱数.最少金钱值是888,最少的 ...
- SRM13 T3 花六游鸟小(结论题)
哇这题是真的喵,HR智商太高辣 这题的难点就是看了题解之后怎么证明题解里的结论... 结论①:深度大于logm的点肯定能达到最大值 证明:显然一个西瓜的属性里0数量一半1数量一半我们取到的1数量最少, ...
- 在CentOS 6.5 中安装JDK 1.7 + Eclipse并配置opencv的java开发环境(二)
一.安装JDK 1.7 1. 卸载OpenJDK rpm -qa | grep java rpm -e --nodeps java-1.6.0-openjdk-1.6.0.0-1.50.1.11.5. ...
- ios轮播
// // ViewController.m // Ocproject // // Created by wenzhe yi on 2018/2/28. // Copyright © 2018年 we ...
- xshell如何让窗口并列排序
如图所示: