zoukankan      html  css  js  c++  java
  • 【bzoj1711/Usaco2007 Open】Dining吃饭——网络流

    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

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

    Sample Input

    4 3 3
    2 2 1 2 3 1
    2 2 2 3 1 2
    2 2 1 3 1 2
    2 1 1 3 3

    输入解释:

    牛 1: 食品从 {1,2}, 饮料从 {1,2} 中选
    牛 2: 食品从 {2,3}, 饮料从 {1,2} 中选
    牛 3: 食品从 {1,3}, 饮料从 {1,2} 中选
    牛 4: 食品从 {1,3}, 饮料从 {3} 中选

    Sample Output

    3
     

     
    听说是三分图啊???就是从源向食物连一条权值为1的边,从饮料向汇连一条权值为1的边,将一头牛x拆成两个点x和x',从该牛能吃的食物向x和x'向能喝的饮料连边,权值也为1。然后跑一遍最大流即可。
    代码:
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int N=105,inf=0x3f3f3f3f;
     5 long long an=0;
     6 int n,D,F,T,tot=1,m=100;
     7 int cur[N*4],first[N*4],d[N*4],q[N*4];
     8 struct node{
     9     int ne,to,w;
    10 }e[500500];
    11 int read(){
    12     int ans=0,f=1;char c=getchar();
    13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    14     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    15     return ans*f;
    16 }
    17 void ins(int u,int v,int w){
    18     e[++tot]=(node){first[u],v,w};first[u]=tot;
    19     e[++tot]=(node){first[v],u,0};first[v]=tot;
    20 }
    21 bool bfs(){
    22     memset(d,-1,sizeof(d));d[0]=0;q[0]=0;
    23     int h=0,t=1;
    24     while(h!=t){
    25         int x=q[h++];if(h>=400)h=0;
    26         for(int i=first[x];i;i=e[i].ne){
    27             int to=e[i].to;
    28             if(d[to]==-1&&e[i].w>0){
    29                 d[to]=d[x]+1;
    30                 q[t++]=to;if(t>=400)t=0;
    31             }
    32         }
    33     }
    34     if(d[T]==-1)return 0;
    35     return 1;
    36 }
    37 int dfs(int x,int a){
    38     if(x==T||!a)return a;
    39     int flow=0,f;
    40     for(int &i=cur[x];i;i=e[i].ne){
    41         int to=e[i].to;
    42         if(d[to]==d[x]+1&&(f=dfs(to,std::min(e[i].w,a)))>0){
    43             e[i].w-=f;
    44             e[i^1].w+=f;
    45             flow+=f;
    46             a-=f;
    47             if(!a)break;
    48         }
    49     }
    50     return flow;
    51 }
    52 int main(){
    53     n=read();F=read();D=read();
    54     T=4*m+1;
    55     for(int i=1;i<=F;i++)ins(0,2*m+i,1);
    56     for(int i=1;i<=D;i++)ins(3*m+i,T,1);
    57     for(int i=1;i<=n;i++)ins(i,i+m,1);
    58     for(int i=1,d,f;i<=n;i++){
    59         f=read();d=read();int a;
    60         while(f--)a=read(),ins(2*m+a,i,1);    
    61         while(d--)a=read(),ins(m+i,3*m+a,1);
    62     }
    63     while(bfs()){
    64         for(int i=0;i<=T;i++)cur[i]=first[i];
    65         an+=dfs(0,inf);
    66     }
    67     printf("%lld",an);
    68     return 0;
    69 }
    bzoj1711
  • 相关阅读:
    FZU 2150 Fire Game
    POJ 3414 Pots
    POJ 3087 Shuffle'm Up
    POJ 3126 Prime Path
    POJ 1426 Find The Multiple
    POJ 3278 Catch That Cow
    字符数组
    HDU 1238 Substing
    欧几里德和扩展欧几里德详解 以及例题CodeForces 7C
    Codeforces 591B Rebranding
  • 原文地址:https://www.cnblogs.com/JKAI/p/7536813.html
Copyright © 2011-2022 走看看