[二分圖最大匹配]
題目大意
完美的牛欄 農夫約翰上個星期剛剛建好了他的新牛棚,他使用了新的擠奶技術.不幸的是,由於工程問題,每 個牛欄都不一樣.第一個星期,農夫約翰隨便地讓奶牛們進入牛欄,但是問題很快地顯露出來:每頭 奶牛都只願意在她們喜歡的那些牛欄中產奶.上個星期,農夫約翰剛剛收集到了奶牛們的愛好的信 息(每頭奶牛喜歡在哪些牛欄產奶).一個牛欄只能容納一頭奶牛,當然,一頭奶牛隻能在一個牛欄 中產奶. 給出奶牛們的愛好的信息,計算大分配方案.
PROGRAM NAME: stall4
INPUT FORMAT
第一行 兩個整數,N (0 <= N <= 200) 和 M (0 <= M <= 200) .N 是農夫約翰的奶牛數量,M 是 新牛棚的牛欄數量.
第二行到第 N+1 行 一共 N 行,每行對應一隻奶牛.第一個數字 (Si) 是這頭奶牛願意在其中產奶 的牛欄的數目 (0 <= Si <= M) .後面的 Si 個數表示這些牛欄的編號.牛欄的編號限定在區間 (1..M) 中,在同一行,一個牛欄不會被列出兩次.
SAMPLE INPUT (file stall4.in)
5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2
OUTPUT FORMAT
只有一行.輸出一個整數,表示多能分配到的牛欄的數量.
SAMPLE OUTPUT (file stall4.out)
4
[題目思路:就是二分圖的最大匹配]
不懂二分圖的戳這裏
/*
ID:***
TASK:stall4
LANG:C++
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define cle(x) memset(x,0,sizeof(x))
const int N=205;
int n,m;
struct ii{
int to,ne;
ii(int to=0,int ne=0):to(to),ne(ne){ }
}ed[N*N*2];
int head[N];
bool used[N];//左邊的點訪問過沒有
int match[N];//左邊點的匹配點
bool crosspath(int u){
for(int i = head[u];i;i=ed[i].ne){
int v=ed[i].to;
if(!used[v]){
used[v]=true;//左邊的點爲u,找到右邊的點,不是以右邊的點進行dfs,而是以右邊的匹配點進行dfs
if(match[v]==0||crosspath(match[v])){
//匹配的開始和結束一定是以match[i]=0,因爲增廣路的端點都是未蓋點
match[v]=u;
return true;
}
}
}
return false;
}
int match_sum,tot;
void hungary(){
for(int i = 1; i <= n; i++){
cle(used);//每一次都要清空去dfs
if(crosspath(i))match_sum++;
}
}
int main(){
freopen("stall4.in","r",stdin);
freopen("stall4.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i = 1; i<= n; i++){
int q;
scanf("%d",&q);
for(int j = 1; j<= q; j++){
int v;
scanf("%d",&v);
ed[++tot]=ii(v,heai]);
head[i]=tot;
}//只需要存單向邊,
}
hungary(
);
printf("%d\n",match_sum);
}
個人認爲那個友鏈講的很好,。。。
要數據的評論哦,,