1. 程式人生 > >【洛谷1640】[SCOI2010]連續攻擊遊戲

【洛谷1640】[SCOI2010]連續攻擊遊戲

題目描述

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

輸入格式:

輸入的第一行是一個整數N,表示lxhgww擁有N種裝備接下來N行,是對這N種裝備的描述,每行2個數字,表示第i種裝備的2個屬性值

輸出格式:

輸出一行,包括1個數字,表示lxhgww最多能連續攻擊的次數。

輸入輸出樣例

輸入樣例#1:

3
1 2
3 2
4 5

輸出樣例#1:

2

說明

對於30%的資料,保證N < =1000

對於100%的資料,保證N < =1000000

題解

要求的是使用屬性值連續的裝備
而每一個屬性的數值只能對應一個裝備
那麼,很顯然,這道題是二分圖匹配
每次對於讀到的兩個屬性值
分別和當前裝備連邊
直接使用匈牙利演算法即可

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 1000100
#define MAXL 2000100
inline int read()
{
       register int x=0,t=1;
       register char ch=getchar();
       while((ch>'9'
||ch<'0')&&ch!='-')ch=getchar(); if(ch=='-'){t=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();} return x*t; } struct Line { int v,next; }e[MAXL]; int h[MAX],cnt=0; int n,a,b; inline void Add(int u,int v) { e[cnt]=(Line){v,h[u]}; h[u]=cnt++; } int match[MAX],sum=1; int vis[MAX]; bool DFS(int x) { for(int i=h[x];i!=-1;i=e[i].next) { register int v=e[i].v; if(vis[v]!=sum) { vis[v]=sum; if(!match[v]||DFS(match[v])) { match[v]=x; return true; } } } return false; } int main() { memset(h,-1,sizeof(h)); n=read(); for(int i=1;i<=n;++i) { a=read(); b=read(); Add(a,i); Add(b,i); } for(int i=1;i<=n;++i) { if(!DFS(i)) { cout<<i-1<<endl; return 0; } else ++sum; } cout<<n<<endl; return 0; }