BZOJ 1711: [Usaco2007 Open]Dingin吃饭

Description

农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品并准备了D (1 <= D <= 100) 种饮料. 他的N (1 <= N <= 100)头牛都以决定了是否愿意吃某种食物和喝某种饮料. 农夫JOHN想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料. 每一件食物和饮料只能由一头牛来用. 例如如果食物2被一头牛吃掉了,没有别的牛能吃食物2.

Input

* 第一行: 三个数: N, F, 和 D

* 第2..N+1行: 每一行由两个数开始F_i 和 D_i, 分别是第i 头牛可以吃的食品数和可以喝的饮料数.下F_i个整数是第i头牛可以吃的食品号,再下面的D_i个整数是第i头牛可以喝的饮料号码.

Output

* 第一行: 一个整数,最多可以喂饱的牛数.

题解:

最大流。

将牛拆为两个点牛1,牛2。

S向每种饮料连边,每种饮料向被喜欢的牛1连边,牛1向牛2连边,牛2向喜欢的食物连边,每种食物向T连边。

流量均为1。

求S-T最大流即可。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
//by zrt
//problem:
using namespace std;
typedef long long LL;
const int inf(0x3f3f3f3f);
const double eps(1e-9);
int n,f;
int H[405],tot,S,T,P[160005],flow[160005],X[160005];
inline void add(int x,int y,int z){
    P[++tot]=y;X[tot]=H[x];H[x]=tot;flow[tot]=z;
}
int d[405];
queue<int> q;
bool bfs(){
    memset(d,0,sizeof d);
    d[S]=1;
    while(!q.empty()) q.pop();
    q.push(S);
    int x;
    while(!q.empty()){
        x=q.front();q.pop();
        if(x==T) return 1;
        for(int i=H[x];i;i=X[i]){
            if(flow[i]>0&&!d[P[i]]){
                d[P[i]]=d[x]+1;
                q.push(P[i]);
            }
        }
    }
    return 0;
}
int dfs(int x,int a){
    if(x==T||a==0) return a;
    int f=a,tmp;
    for(int i=H[x];i;i=X[i]){
        if(d[P[i]]==d[x]+1&&flow[i]>0){
            tmp=dfs(P[i],min(a,flow[i]));
            a-=tmp;
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            if(!a) break;
        }
    }
    if(f==a) d[x]=-1;
    return f-a;
}
int Dinic(){
    int f=0;
    while(bfs()){
        f+=dfs(S,inf);
    }
    return f;
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    S=403,T=404;
    tot=1;
    int d;
    scanf("%d%d%d",&n,&f,&d);
    //n 1..n n+1..n+n
    //f 2*n+1..2*n+f
    //d 2*n+f+1..2*n+f+d
    for(int i=1;i<=n;i++){
        add(i,i+n,1);
        add(i+n,i,0);
    }
    for(int i=1;i<=f;i++){
        add(S,i+2*n,1);
        add(i+2*n,S,0);
    }
    for(int i=1;i<=d;i++){
        add(2*n+f+i,T,1);
        add(T,2*n+f+i,0);
    }
    for(int i=1;i<=n;i++){
        int fi,di;
        scanf("%d%d",&fi,&di);
        int x;
        for(int j=1;j<=fi;j++){
            scanf("%d",&x);
            add(x+2*n,i,1);
            add(i,x+2*n,0);
        }
        for(int j=1;j<=di;j++){
            scanf("%d",&x);
            add(i+n,x+2*n+f,1);
            add(x+2*n+f,i+n,0);
        }
    }
    printf("%d\n",Dinic());
    return 0;
}
时间: 2024-12-29 11:38:07

BZOJ 1711: [Usaco2007 Open]Dingin吃饭的相关文章

1711: [Usaco2007 Open]Dingin吃饭

1711: [Usaco2007 Open]Dingin吃饭 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 560  Solved: 290[Submit][Status][Discuss] Description 农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品

BZOJ 1711: [Usaco2007 Open]Dining吃饭

1711: [Usaco2007 Open]Dining吃饭 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 902  Solved: 476[Submit][Status][Discuss] Description 农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品

bzoj 1711 [Usaco2007 Open]Dining吃饭&amp;&amp;poj 3281 Dining

最大流. 这东西好像叫三分图匹配. 源点向每个食物点连一条容量为1的边. 每个饮料点向汇点连一条容量为1的边. 将每个牛点拆点,食物点向喜欢它的牛的入点连一条容量为1的边,牛的出点向它喜欢的饮料点连一条容量为1的边. 最大流即为答案,每头牛拆点是为了保证每头牛只有一种食物和一种饮料. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #inc

BZOJ1711: [Usaco2007 Open]Dingin吃饭

1711: [Usaco2007 Open]Dingin吃饭 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 508  Solved: 259[Submit][Status] Description 农 夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品并准备了D (1

【BZOJ】1711: [Usaco2007 Open]Dining吃饭

[算法]最大流 [题解] S连向食物连向牛连向牛'连向饮料连向T. 经典的一个元素依赖于两个元素的建图方式. #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int maxn=100010,inf=0x3f3f3f3f; struct edge{int v,flow,from;}e[maxn]; int firs

【最大流】【Dinic】bzoj1711 [Usaco2007 Open]Dingin吃饭

把牛拆点,互相连1的边. 把牛的食物向牛连边,把牛向牛的饮料连边. 把源点向牛的食物连边,把牛的饮料向汇点连边. 要把牛放在中间,否则会造成一头牛吃了自己的食物后又去喝别的牛的饮料的情况. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define INF 2147483647 #define MAXN 411 #def

bzoj1711【Usaco2007 Open】Dingin 吃饭

1711: [Usaco2007 Open]Dingin吃饭 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 670  Solved: 343 [Submit][Status][Discuss] Description 农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种

矩阵乘法专题2——bzoj 1706 [usaco2007 Nov] relays 奶牛接力跑 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24960651 [原题] 1706: [usaco2007 Nov]relays 奶牛接力跑 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 340  Solved: 162 [Submit][Status] Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力

BZOJ 1711:[Usaco2007 Open]Dining吃饭(最大流)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1711 [题目大意] 每头牛都有一些喜欢的饮料和食物, 现在有一些食物和饮料,但是每样只有一份, 现在要求得到最多的牛使得都可以获得一份喜欢的饮料和一份喜欢的食物 [题解] 为了避免一份牛占用过多的资源,我们对牛进行拆点,增加边作为限制, 然后源点连接食物,汇点连接饮料,求最大流即可. [代码] #include <cstdio> #include <algorithm>