USACO Section4.2 The Perfect Stall &&POJ1274

[二分圖最大匹配]
題目大意
完美的牛欄 農夫約翰上個星期剛剛建好了他的新牛棚,他使用了新的擠奶技術.不幸的是,由於工程問題,每 個牛欄都不一樣.第一個星期,農夫約翰隨便地讓奶牛們進入牛欄,但是問題很快地顯露出來:每頭 奶牛都只願意在她們喜歡的那些牛欄中產奶.上個星期,農夫約翰剛剛收集到了奶牛們的愛好的信 息(每頭奶牛喜歡在哪些牛欄產奶).一個牛欄只能容納一頭奶牛,當然,一頭奶牛隻能在一個牛欄 中產奶. 給出奶牛們的愛好的信息,計算大分配方案.
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);
}

個人認爲那個友鏈講的很好,。。。
要數據的評論哦,,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章