1. 程式人生 > >1854: [Scoi2010]遊戲

1854: [Scoi2010]遊戲

Description

lxhgww最近迷上了一款遊戲,在遊戲裡,他擁有很多的裝備,每種裝備都有2個屬性,這些屬性的值用[1,10000]之間的數表示。當他使用某種裝備時,他只能使用該裝備的某一個屬性。並且每種裝備最多隻能使用一次。 遊戲進行到最後,lxhgww遇到了終極boss,這個終極boss很奇怪,攻擊他的裝備所使用的屬性值必須從1開始連續遞增地攻擊,才能對boss產生傷害。也就是說一開始的時候,lxhgww只能使用某個屬性值為1的裝備攻擊boss,然後只能使用某個屬性值為2的裝備攻擊boss,然後只能使用某個屬性值為3的裝備攻擊boss……以此類推。 現在lxhgww想知道他最多能連續攻擊boss多少次?


二分圖

由於屬性\(\in\)[1,10000] 所以一邊是屬性另一邊是裝備

不是很清楚\(dinic\)到底能不能跑過這道題QAQ所以我寫的是匈牙利

\(memset\)清除訪問標記會超時,直接把bool陣列開成時間戳就行啦


#include<iostream>
#include<cstdio>
#include<cstring>
#define N 10001
#define M 2100001 
using namespace std;

int maxx,t,m,n,k,d[M],ver[M],nex[M],cnt,head[M],a,b,ans,bl[M];

inline void add(int x,int y){ ver[++cnt]=y; nex[cnt]=head[x]; head[x]=cnt; }

bool xyl(int x)
{
    for(int i=head[x];i;i=nex[i]) if(bl[ver[i]]<=ans)
    {
        bl[ver[i]]=ans+1;
        if(!d[ver[i]] || xyl(d[ver[i]])) {d[ver[i]]=x; return 1;}
    }
    return 0;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,i), add(b,i);
        maxx=max(maxx,max(a,b));
    }
    for(ans=0;ans<N;ans++) if(!xyl(ans+1)) break;
    printf("%d",ans);
}