1. 程式人生 > >BZOJ1191:超級英雄(二分圖匹配)

BZOJ1191:超級英雄(二分圖匹配)

[HNOI2006]超級英雄Hero

題目連結:https://www.lydsy.com/JudgeOnline/problem.php?id=1191

Description:

現在電視臺有一種節目叫做超級英雄,大概的流程就是每位選手到臺上回答主持人的幾個問題,然後根據回答問題的 多少獲得不同數目的獎品或獎金。主持人問題準備了若干道題目,只有當選手正確回答一道題後,才能進入下一題 ,否則就被淘汰。為了增加節目的趣味性並適當降低難度,主持人總提供給選手幾個“錦囊妙計”,比如求助現場 觀眾,或者去掉若干個錯誤答案(選擇題)等等。這裡,我們把規則稍微改變一下。假設主持人總共有m道題,選 手有n種不同的“錦囊妙計”。主持人規定,每道題都可以從兩種“錦囊妙計”中選擇一種,而每種“錦囊妙計” 只能用一次。我們又假設一道題使用了它允許的錦囊妙計後,就一定能正確回答,順利進入下一題。現在我來到了 節目現場,可是我實在是太笨了,以至於一道題也不會做,每道題只好藉助使用“錦囊妙計”來通過。如果我事先 就知道了每道題能夠使用哪兩種“錦囊妙計”,那麼你能告訴我怎樣選擇才能通過最多的題數嗎? Input:
輸入檔案的一行是兩個正整數n和m(0 < n <1001,0 < m < 1001)表示總共有n中“錦囊妙計”,編號為0~n-1,總共有m個問題。
以下的m行,每行兩個數,分別表示第m個問題可以使用的“錦囊妙計”的編號。
注意,每種編號的“錦囊妙計”只能使用一次,同一個問題的兩個“錦囊妙計”可能一樣。 Output: 第一行為最多能通過的題數p Sample Input: 5 6

3 2
2 0

0 3

0 4

3 2

3 2 Sample Output: 4 題解: 裸的二分圖匹配,一個錦囊對應一個問題,問通過的最大問題數。
  程式碼如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int N = 1005 ;
int n,m,ans=0;
int map[N][N]={0},check[N],matching[N];

inline int dfs(int x){
    for(int i=0;i<n;i++){
        if(map[x][i] &&!check[i]){
            check[i]
=1; if(matching[i]==-1 || dfs(matching[i])){ matching[i]=x; return 1; } } } return 0; } int main(){ cin>>n>>m; memset(matching,-1,sizeof(matching)); for(int i=1,x,y;i<=m;i++){ cin>>x>>y; map[i][x]=map[i][y]=1; } for(int i=1;i<=m;i++){ memset(check,0,sizeof(check)); if(dfs(i)) ans++; else break ; } cout<<ans; return 0; }