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);
}

个人认为那个友链讲的很好,。。。
要数据的评论哦,,

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