1. 程式人生 > >打鳥 二分圖最大匹配

打鳥 二分圖最大匹配

include string 遊戲 ica times || 輸出 margin cout

有一款名叫打鳥的遊戲,遊戲中有 mm 只鳥在一個 n \times nn×n 的網格中。你可以每次選擇消滅一橫排的鳥,也可以選擇消滅一豎排的鳥(小鳥那麽萌,為什麽要消滅他)。你的任務是消滅地圖上所有的小鳥,那麽你最少需要多少次操作,才能消滅所有的小鳥。

輸入格式

第一行輸入兩個整數 n (1\leq n \leq 10000)n(1n10000),m (1\leq m \leq 20000)m(1m20000),分別表示網格的大小和小鳥的數量。

接下來的 mm 行,每行輸入兩個整數 x, yx,y,代表這只鳥在地圖中的坐標。(1 \leq x,y \leq n1x,yn)

輸出格式

輸出消滅所有小鳥需要的最少操作數。

樣例輸入

3 4
1 2
2 1
3 3
2 3

樣例輸出

3

分析:
問題可以轉換有多少個點互相不同行或不同列。
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=10010;
vector<int>map[maxn];
bool book[maxn];
int match[maxn];
bool dfs(int s){
    book[s]=1;
    for
(int i=0;i<map[s].size();++i){ int v=map[s][i]; if(!match[v]||!book[match[v]]&&dfs(match[v])){ match[v]=s; return 1; } } return 0; } int main(){ int n,m; cin>>n>>m; for(int i=1;i<=m;++i){ int x,y; cin
>>x>>y; map[x].push_back(y); } int ans=0; for(int i=1;i<=n;++i){ memset(book,0,sizeof(book)); if(dfs(i))++ans; } cout<<ans; return 0; }

打鳥 二分圖最大匹配