[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;
}
posted @ 2023-06-15 07:34  Ciaxin  阅读(63)  评论(0编辑  收藏  举报