1. 程式人生 > >SCOI2010 遊戲

SCOI2010 遊戲

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

一眼就是二分圖。注意一個二分圖的套路,最大匹配的意義是選了這個點後,那個匹配點也不能再被選了。

#include<bits/stdc++.h>
using namespace std;
const int Maxn=1000005;
struct Edge{
	int cnt,h[Maxn],to[Maxn*2],next[Maxn*2];
	inline void add(int x,int y){
		next[++cnt]=h[x];to[cnt]=y;h[x]=cnt;
	}
}e;
#define to e.to[p]
bool vst[Maxn];
int my[Maxn];
int top,s[Maxn];
bool findpath(int x){
	for(int p=e.h[x];p;p=e.next[p])if(!vst[to]){
		vst[to]=1;s[++top]=to;
		if(!my[to]||findpath(my[to])){
			my[to]=x;
			return 1;
		}
	}
	return 0;
}
int main(){
	int n;scanf("%d",&n);
	for(int i=1;i<=n;++i){
		int x,y;scanf("%d%d",&x,&y);
		e.add(x,i),e.add(y,i);
	}
	for(int i=1;i<=10001;++i){
		for(int j=1;j<=top;++j)vst[s[j]]=0;
		top=0;
		if(!findpath(i)){
			cout<<i-1<<"\n";
			break;
		}
	}	
	return 0;
}