题目链接

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 游戏 二分图匹配 || 并查集的更多相关文章

  1. BZOJ 1854 游戏(二分图匹配或并查集)

    此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个 ...

  2. HDU-3081-Marriage Match II 二分图匹配+并查集 OR 二分+最大流

    二分+最大流: 1 //题目大意:有编号为1~n的女生和1~n的男生配对 2 // 3 //首先输入m组,a,b表示编号为a的女生没有和编号为b的男生吵过架 4 // 5 //然后输入f组,c,d表示 ...

  3. BZOJ 1854: [Scoi2010]游戏(二分图匹配/并查集)

    题面: https://www.lydsy.com/JudgeOnline/problem.php?id=1854 题解: 1.二分图匹配: 首先我们发现每件装备只能在两种属性中选一种.因此,我们以每 ...

  4. [BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法 ...

  5. HDU 3081:Marriage Match II(二分图匹配+并查集)

    http://acm.hdu.edu.cn/showproblem.php?pid=3081 题意:有n个男生n个女生,他们只有没有争吵或者女生a与男生A没有争吵,且女生b与女生a是朋友,因此女生b也 ...

  6. HDU 3081 Marriage Match II (二分图,并查集)

    HDU 3081 Marriage Match II (二分图,并查集) Description Presumably, you all have known the question of stab ...

  7. BZOJ.2054.疯狂的馒头(并查集)

    BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...

  8. noip 2010 关押罪犯 二分答案+二分图染色 || 并查集

    题目链接 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值&q ...

  9. 2021.08.03 BZOJ 疯狂的馒头(并查集)

    2021.08.03 BZOJ 疯狂的馒头(并查集) 疯狂的馒头 - 题目 - 黑暗爆炸OJ (darkbzoj.tk) 重点: 1.并查集的神奇运用 2.离线化 题意: 给一个长为n的序列,进行m次 ...

随机推荐

  1. [CLR via C#]异常和状态管理

    当CLR检测到某个正在运行的.NET应用程序处于一种特殊的正常执行顺序被打断的状态时,会生成一个异常对象来表示这个错误,并将此对象在方法调用堆栈中向上传送.如果一个程序引发了一个异常却没有处理,CLR ...

  2. [计算机网络-应用层] P2P应用

    首先我们要先来区分一下下面的几种体系结构: CS:Client/Server 客户-服务器结构BS:Browser/Server  浏览器-服务器结构 P2P:Peer to Peer 对等结构 BS ...

  3. <hx>标签 字体自动加粗 自动换行

    <hx>标签 字体自动加粗 自动换行

  4. 可持久化Treap

    终于写了一次可持久化Treap,做的是可持久化序列的模板题. Treap Treap=Tree+Heap,是一个随机化的数据结构.它的每个节点至少有两个关键字,一个是我们要存储的\(val\),一个是 ...

  5. 【刷题】BZOJ 1003 [ZJOI2006]物流运输

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  6. BZOJ4653 & 洛谷1712 & UOJ222:[NOI2016]区间——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4653 https://www.luogu.org/problemnew/show/P1712 ht ...

  7. Manacher以及回文树算法学习

    Manacher以及回文树算法学习 一.Manacher 关于\(Manacher\),这篇博客 讲的很清楚. 大致总结一下 为了将长度为奇数的回文串和长度为偶数的回文串一起考虑,需要在原字符串中插入 ...

  8. linux 文件检索操作

    linux命令太多了,作为一个后端开发人员,常用的也就这几个 uname -a 查看版本 tail tail -f /data/wealth-consignment-service/logs/stat ...

  9. JSP页面中的Meta标签详解

    Meta标签详解 相信大家在平时开发中最常接触的页面就是html和jsp了,可在这两个页面中有一个Meta标签你天天都会看见,可是你真的了解这个标签的一些其他用处吗?今天给大家介绍一些该标签的其他应用 ...

  10. js正则:两边字符固定,中间任意字符

    求些一个js正则!两边字符固定,中间任意字符.在一个长字符串里面匹配一小段,这一小段字符串开头和结尾都是固定的字符,就是中间是任意长度的字符.怎么写? /aa.+aa/ aa是你的固定字符,如果是反斜 ...