[luogu1640 SCOI2010]連續攻擊遊戲 (二分圖匹配)
阿新 • • 發佈:2018-08-16
() oss ring ems put printf class names 表示
[傳送門] (https://www.luogu.org/problemnew/show/P1640)
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
Solution
二分圖匹配 通過更改vis標記減少memset
Code
//By Menteur_Hxy #include <vector> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define F(i,a,b) for(register int i=(a);i<=(b);i++) using namespace std; int read() { int x=0,f=1; char c=getchar(); while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();} while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar(); return x*f; } const int N=1000010; int n,ans; int vis[N],fr[N]; vector<int> V[N]; bool dfs(int x) { int siz=V[x].size(); F(i,0,siz-1) { int v=V[x][i]; if(vis[v]!=ans+1) { vis[v]=ans+1; if(!fr[v]||dfs(fr[v])) { fr[v]=x; return 1; } } } return 0; } int main() { n=read(); F(i,1,n) { int x=read(),y=read(); V[x].push_back(i); V[y].push_back(i); } F(i,1,10000) { if(!dfs(i)) break; ans++; } printf("%d\n",ans); return 0; }
[luogu1640 SCOI2010]連續攻擊遊戲 (二分圖匹配)