[SCOI2010] 连续攻击游戏-题解
题目描述
\(\text{lxhgww}\) 最近迷上了一款游戏,在游戏里,他拥有很多的装备(\(n \le 10^6\)),每种装备都有 \(2\) 个属性,这些属性的值用 \([1,10000]\) 之间的数表示。
当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。
游戏进行到最后,\(\text{lxhgww}\) 遇到了终极 \(\text{boss}\),这个终极 \(\text{boss}\) 很奇怪,攻击他的装备所使用的属性值必须从 \(1\) 开始连续递增地攻击,才能对 \(\text{boss}\) 产生伤害。
也就是说一开始的时候,\(\text{lxhgww}\) 只能使用某个属性值为 \(1\) 的装备攻击 \(\text{boss}\),然后只能使用某个属性值为 \(2\) 的装备攻击 \(\text{boss}\),然后只能使用某个属性值为 \(3\) 的装备攻击 \(\text{boss}\)……以此类推。
现在 \(\text{lxhgww}\) 想知道他最多能连续攻击 \(\text{boss}\) 多少次?
\(\text{SOL}\)
由于攻击是连续的,所以在第 \(k\) 次攻击的伤害为 \(k\)。
第 \(k\) 次的攻击将会对应一个装备 \(i\),否则应该停止攻击。
装备 \(i\) 一定也会对应着两次攻击伤害,由此将伤害和装备之间建立联系。
可以看出形成了二分图,进行最大匹配即可。 进行匹配时,用攻击伤害作为待匹配点,如果在无法匹配时,即无法攻击时,跳出。
\(\text{CODE}\)
/* [SCOI2010] 连续攻击游戏
由于攻击是连续的,所以在第 k 次攻击的伤害为 k。
第 k 次的攻击将会对应一个装备 i,否则应该停止攻击。
装备 i 一定也会对应着两次攻击伤害,由此将伤害和装备之间建立联系。
可以看出形成了二分图,进行最大匹配即可。
进行匹配时,用攻击伤害作为待匹配点,可很好的在无法怕匹配
*/
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+7;
int to[N],nxt[N],hd[N],vis[N],lx[N];
int n,cnt,m=-1,ans,tim;
inline void addedge(int u,int v) {
to[++cnt]=v;
nxt[cnt]=hd[u];
hd[u]=cnt;
}
bool dfs(int u) {
for(int i=hd[u];i;i=nxt[i]) {
if(vis[to[i]]==tim)continue;
vis[to[i]]=tim;
if(!lx[to[i]] || dfs(lx[to[i]])) {
lx[to[i]]=u; return true;
}
}
return false;
}
int main() {
scanf("%d",&n);
for(int i=1,a,b;i<=n;i++) {
scanf("%d%d",&a,&b);
addedge(a,i); addedge(b,i);
m=max(m,max(a,b));
}
for(int i=1;i<=m;i++) {
tim++; // vis[]
if(dfs(i)) ans++;
else break;
}
printf("%d",ans);
return 0;
}