题解 P1894 【[USACO4.2]完美的牛栏The Perfect Stall】

题面

农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术。不幸的是,由于工程问题,每个牛栏都不一样。第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶。上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶)。一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶。

给出奶牛们的爱好的信息,计算最大分配方案。

题意

如题面。

题解

  1. 每只奶牛只喜欢在自己喜欢的牛棚里面产奶。(匹配)
  2. 一个牛棚只能容纳一头奶牛。
  3. 最大的分配方案。

匈牙利算法(匹配算法),个人感觉实质上就是一个DFS的匹配算法。

伪代码:

bool dfs(int x)
{
    while(找到Xi的关联顶点Yj){
          if(顶点Yj不在增广路径上){
                将Yj加入增广路
               if(Yj是未覆盖点或者Yj的原匹配点Xk能找到增广路径){ //扩充集合M
                      将Yj的匹配点改为Xi;
                      返回true;
           }
      }
               返回false;
}

根据题意可以知道这是一道匈牙利算法的模板题。于是开始根据伪代码来造代码。

代码

代码1(my code)

#include<bits/stdc++.h>
using namespace std;

const int maxn = 10010;
const int maxm = 10010;
int n,m,tong[maxm],ans;
bool vis[maxn],love[maxn][maxm];

inline int read(){
    int k=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();}
    return k*f;
}

inline void init()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++){
        int l=read();
        while(l--){
            love[i][read()]=true;
        }
    }
}

bool dfs(int x)
{
    for(int i = 1;i <= m;++i)
    {
        if(!vis[i] && love[x][i])
        {
            vis[i] = true;
            if(tong[i]==0 || dfs(tong[i]))
            {
                tong[i] = x;
                return true;
            }
        }
    }

    return false;
}

int main(int argc, char const *argv[])
{
    init();

    for(int i = 1;i <= n;++i)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i)) ans++;
    }

    cout << ans;

    return 0;
}

代码2(rank 1)

#include <cstdio>
#include <cstring>
using namespace std;
#define M(x) memset(x, false, sizeof(x))
const int maxn = 205;
int N, M, ans, link[maxn];
bool vis[maxn], A[maxn][maxn];
bool dfs(int x){
    for(int i = 1; i <= N; i++)
        if(A[x][i] && !vis[i]){
            vis[i] = true;
            if(!link[i] || dfs(link[i])){
                link[i] = x;
                return true;
            }
        }
    return false;
}
inline int GetInt(){
    char x;
    int ret;
    while((x = getchar()) < '0' || x > '9');
    ret = x - '0';
    while((x = getchar()) >= '0' && x <= '9') ret = ret * 10 + x - '0';
    return ret;
}
int main(){
    N = GetInt(), M = GetInt();
    for(int i = 1; i <= N; i++){
        int sum;
        sum = GetInt();
        for(int j = 1, OP; j <= sum; j++){
            OP = GetInt();
            A[i][OP] = true;
        }
    }
    for(int i = 1; i <= N; i++){
        M(vis);
        if(dfs(i)) ans++;
    }
    printf("%d", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Chicago/p/9920700.html

时间: 2024-08-12 14:51:21

题解 P1894 【[USACO4.2]完美的牛栏The Perfect Stall】的相关文章

洛谷P1894 [USACO4.2]完美的牛栏The Perfect Stall

P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶).一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶. 给出奶牛们的爱好的信息,计算最大分配方案. 输入输出

洛谷P1894 [USACO4.2]完美的牛栏The Perfect Stall(二分图)

P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶).一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶. 给出奶牛们的爱好的信息,计算最大分配方案. 输入输出

洛谷 P1894 [USACO4.2]完美的牛栏The Perfect Stall

P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶).一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶. 给出奶牛们的爱好的信息,计算最大分配方案. 输入输出

P1894 [USACO4.2]完美的牛栏The Perfect Stall

题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶).一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶. 给出奶牛们的爱好的信息,计算最大分配方案. 输入输出格式 输入格式: 第一行 两个整数,N (0 <= N <= 200) 和

[USACO4.2]完美的牛栏The Perfect Stall

题目:USACO Training 4.2(在官网上提交需加文件输入输出).洛谷P1894. 题目大意:有n头奶牛m个牛栏,每头牛只会在自己喜欢的牛栏里产奶,问一次最多有多少奶牛能产奶. 解题思路:二分图匹配.这里我用了网络流,先建立超级源点和超级汇点,跑最大流即可.以下是Dinic算法的代码. C++ Code: #include<cstdio> #include<queue> #include<cstring> #include<algorithm> #

洛谷 1894 [USACO4.2]完美的牛栏The Perfect Stall

[题解] 其实是个二分图最大匹配的模板题,直接上匈牙利算法就好了. 1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #define rg register 5 using namespace std; 6 int n,m,E,ans,T,tot,last[N],v[N],from[N]; 7 struct edge{ 8 int to,pre; 9 }e[N*N]; 10 inline int read(){

匈牙利算法 cogs 886. [USACO 4.2] 完美的牛栏

886. [USACO 4.2] 完美的牛栏 ★★☆   输入文件:stall4.in   输出文件:stall4.out   简单对比时间限制:1 s   内存限制:128 MB USACO/stall4(译by Felicia Crazy) 描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶

[USACO 4.2] 完美的牛栏

★★☆   输入文件:stall4.in   输出文件:stall4.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/stall4(译by Felicia Crazy) 描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶.上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶

[转]完美洗牌(Perfect Shuffle)问题

[转]原博文地址:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.09.md 完美洗牌算法 题目详情 有个长度为2n的数组{a1,a2,a3,...,an,b1,b2,b3,...,bn},希望排序后{a1,b1,a2,b2,....,an,bn},请考虑有无时间复杂度o(n),空间复杂度0(1)的解法. 题目来源:此题是去年2013年UC的校招笔试题,看似简单,按照题目所要