连续攻击游戏【P1640洛谷】二分图匹配变形【好题】【每次memset太慢了,用时间戳id。】
lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。现在lxhgww想知道他最多能连续攻击boss多少次?
输入格式
输入的第一行是一个整数N,表示lxhgww拥有N种装备接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值
输出格式
输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。
输入输出样例
3 1 2 3 2 4 5
2
说明/提示
Limitation
对于30%的数据,保证N < =1000
对于100%的数据,保证N < =1000000
来源:SCOI 2010
【总结】
二分图的最大匹配问题,做法很巧妙,但是很难想到。
第一眼看到这个题想到的是将某个物品的两个属性分成左右部点,但是很难解决本题,尤其是在处理一个物品只能用一种属性的时候。所以我们不妨换一种思路,对于物品 ii 的属性 a,ba,b ,分别从 aa 和 bb 向 ii 连一条有向边。将物品的属性当做左部点,编号当做右部点,求最大匹配即可。
这样为什么是正确的呢?我们可以考虑匈牙利算法的具体过程:在匹配值为 ii 的技能时,那么 11 到 i-1i−1 的属性肯定已经匹配完成,所以如果 ii 对应的编号 jj 被匹配了的话,那么就让匹配 jj 的那个属性 pp 再去找别的物品标号匹配,形象地说,就是用别的物品来释放攻击力为 pp 的这个技能,用 jj 这个物品释放攻击力为 ii 的技能。如果找到这样一条增广路,那么就说明当前可以匹配,ans++。
【收获】:每次memset太慢了,用时间戳id。
AC代码:【链接矩阵】
#include<bits/stdc++.h> using namespace std; #define maxn 1000009 int now; inline int read(){ , f = ; ; c = getchar();} + c - ', c = getchar(); return x * f; } int match[maxn]; int vis[maxn]; struct Edge{ int to; int next; }e[*maxn]; ; int head[maxn]; void add(int u,int v){ e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt++; } int dfs(int u){ int temp; for(int i=head[u];i;i=e[i].next){ temp=e[i].to; if(vis[temp]!=now){ vis[temp]=now; // vis[temp]=1; ||dfs(match[temp])){ match[temp]=u; ; } } } ; } int main(){ int n;int x,y; //scanf("%d",&n); n=read(); ;i<=n;i++){ x=read(); y=read(); add(x,i); add(y,i); } ; ;i<=n;i++){ now++; if(dfs(i)) ans++; else{ break; } } printf("%d\n",ans); ; }
【vector存图】
#include<bits/stdc++.h> using namespace std; #define maxn 1000009 int match[maxn]; int vis[maxn]; int id; vector<int> v[maxn]; int dfs(int u){ ;i<v[u].size();i++){ int temp=v[u][i]; if(vis[temp]!=id){ vis[temp]=id; ||dfs(match[temp])){ match[temp]=u; ; } } } ; } int main(){ int n; scanf("%d",&n); ;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); v[x].push_back(i); v[y].push_back(i); } memset(match,,sizeof(match)); ; ;i<=n;i++){ id++; if(dfs(i)) ans++; else{ break; } } cout<<ans<<endl; ; }
连续攻击游戏【P1640洛谷】二分图匹配变形【好题】【每次memset太慢了,用时间戳id。】的更多相关文章
- 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)
[洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...
- 洛谷 P5596 【XR-4】题
洛谷 P5596 [XR-4]题 洛谷传送门 题目描述 小 X 遇到了一道题: 给定自然数 a,ba,b,求满足下列条件的自然数对 (x,y)(x,y) 的个数: y^2 - x^2 = ax + b ...
- 洛谷P1640 SCOI2010 连续攻击游戏 (并查集/匹配)
本题介绍两种做法: 1 并查集 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1000005; 4 int ...
- 洛谷P1000 超级玛丽游戏(洛谷新手村1-1-1)
题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用. 建议完成本题目后继续尝试P1001.P1008. 题目描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级玛丽中的一个场景. *** ...
- cogs_396_魔术球问题_(最小路径覆盖+二分图匹配,网络流24题#4)
描述 http://cojs.tk/cogs/problem/problem.php?pid=396 连续从1开始编号的球,按照顺寻一个个放在n个柱子上,\(i\)放在\(j\)上面的必要条件是\(i ...
- 洛谷P3676 小清新数据结构题 【树剖 + BIT】
题目链接 洛谷P3676 题解 我们先维护\(1\)为根的答案,再考虑换根 一开始的答案可以\(O(n)\)计算出来 考虑修改,记\(s[u]\)表示\(u\)为根的子树的权值和 当\(u\)节点产生 ...
- 【题解】洛谷P1072 Hankson的趣味题 (gcd和lcm的应用)
洛谷P1072:https://www.luogu.org/problemnew/show/P1072 思路 gcd(x,a0)=a1 lcm(x,b0)=b1→b0*x=b1*gcd(x,b0) ( ...
- 【洛谷】CYJian的水题大赛 解题报告
点此进入比赛 \(T1\):八百标兵奔北坡 这应该是一道较水的送分题吧. 理论上来说,正解应该是DP.但是,.前缀和优化暴力就能过. 放上我比赛时打的暴力代码吧(\(hl666\)大佬说这种做法的均摊 ...
- 洛谷 P3676 - 小清新数据结构题(动态点分治)
洛谷题面传送门 题目名称好评(实在是太清新了呢) 首先考虑探究这个"换根操作"有什么性质.我们考虑在换根前后虽然每个点的子树会变,但整棵树的形态不会边,换句话说,割掉每条边后,得到 ...
随机推荐
- Feign【token传递】
使用feign调用服务的时候,存在一个问题,比如当前服务调用A服务,在请求头中包含了某些特殊的字段信息,比如当前操作人的token信息,调用A的时候可以正常拿到token,然而在去调用B服务的时候,可 ...
- Java 语言 ArrayList 和 JSONArray 相互转换
Java 语言 ArrayList 和 JSONArray 相互转换 本篇主要讲解 ArrayList 和 fastjson 中的 JSONArray相互转换的几种常用方式,以实体类 Student. ...
- PAT甲级 图 相关题_C++题解
图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...
- 只学python行吗
常言道:"流水的语言,铁打的Python",目前它可以说是已经"睥睨天下,傲视群雄"了.它天生丽质,易于读写,非常实用,从而赢得了 广泛的群众基础,被誉为&qu ...
- 下载GDB调试工具peda
命令: 1.git clone https://github.com/longld/peda.git ~/peda 2.echo "source ~/peda/peda.py" & ...
- java字节和字符的区别
字节: 1.bit=1 二进制数据0或1 2.byte=8bit 1个字节等于8位 存储空间的基本计量单位 3.一个英文字母=1byte=8bit 1个英文字母是1个字节,也就是8位 4.一个汉字 ...
- Redis键的基本操作
1.Redis键的键名查询 ·命令名称:KEYS ·语法:KEYS pattern ·Pattern的用法: ? 任意一个字符 * 任意个任意字符 [ae] a或者e [^ae] 除了a和e [a-c ...
- (二十六)JavaBean
一.定义 1 JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法暴露给其它程序 ...
- call、apply、bind一直是不求甚解!
一直感觉代码中有call和apply就很高大上(看不懂),但是都草草略过,今天非要弄明白!以前总是死记硬背:call.apply.bind 都是用来修改函数中的this,传参时,call是一个个传参, ...
- puml 用于代码注释
notebook 笔记本 @startuml rectangle sql_decode.py{ object SQLDataset object Name SQLDataset : meta = &q ...