zoukankan      html  css  js  c++  java
  • poj 1149 PIGS

    有m个猪圈,每个猪圈上有若干头猪。有n个买猪的人,按顺序来买猪,每个人只会买固定几个猪圈里的猪,并且买猪有上限。当一个人买完猪后,他所买的那几个猪圈的猪可以互相走,问n个人依次买完,最多买多少头猪。

    1<=m<=1000.1<=n<=100.

    最大流。

    裸的建图(每个人买猪的情况就建一层点)点数边数爆炸。

    正解的建图是将猪圈间的转移放到买猪的人上,整张图只有n个点代表n个人。

    源点到每个猪圈来买的第一个人连一条容量为该猪圈初始猪的数量的边。

    对于每个猪圈,从第i个人来买的人向第i+1个来买的人连一条容量为正无穷的边。

    每个人向汇点连一条容量为此人买猪上限的边。

    最大流即为答案。

    正无穷边实现流量传递,对于一个人买完离开时的情况,所有他能买的猪圈的流量都汇在他身上,由他连向下一个买的人,这就实现了猪圈间的流量传递。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 const int dian=105;
     8 const int diann=1005;
     9 const int bian=200005;
    10 const int INF=0x3f3f3f3f;
    11 int h[dian],nxt[bian],ver[bian],val[bian],ch[dian],cr[dian];
    12 int numm[diann],aa[diann][dian],rnum[diann],mnum[dian];
    13 int n,m,tot,a,b;
    14 int S,T;
    15 int add(int a,int b,int c){
    16     tot++;ver[tot]=b;val[tot]=c;nxt[tot]=h[a];h[a]=tot;
    17     tot++;ver[tot]=a;val[tot]=0;nxt[tot]=h[b];h[b]=tot;
    18 }
    19 bool tell(){
    20     memset(ch,-1,sizeof(ch));
    21     queue<int>q;
    22     q.push(S);
    23     ch[S]=0;
    24     while(!q.empty()){
    25         int t=q.front();
    26         q.pop();
    27         for(int i=h[t];i;i=nxt[i])
    28             if(ch[ver[i]]==-1&&val[i]){
    29                 ch[ver[i]]=ch[t]+1;
    30                 q.push(ver[i]);
    31             }
    32     }
    33     return ch[T]!=-1;
    34 }
    35 int zeng(int a,int b){
    36     if(a==T)
    37         return b;
    38     int r=0;
    39     for(int i=cr[a];i&&b>r;i=nxt[i])
    40         if(ch[ver[i]]==ch[a]+1&&val[i]){
    41             int t=zeng(ver[i],min(b-r,val[i]));
    42             val[i]-=t,r+=t,val[i^1]+=t;
    43             if(val[i])
    44                 cr[a]=i;
    45         }
    46     if(!r)
    47         ch[a]=-1;
    48     return r;
    49 }
    50 int dinic(){
    51     int r=0,t;
    52     while(tell()){
    53         for(int i=1;i<=n+2;i++)
    54             cr[i]=h[i];
    55         while(t=zeng(S,INF))
    56             r+=t;
    57     }
    58     return r;
    59 }
    60 int main(){
    61     memset(h,0,sizeof(h));
    62     memset(nxt,0,sizeof(nxt));
    63     memset(rnum,0,sizeof(rnum));
    64     tot=1;
    65     scanf("%d%d",&m,&n);
    66     S=n+1,T=n+2;
    67     for(int i=1;i<=m;i++)
    68         scanf("%d",&numm[i]);
    69     for(int i=1;i<=n;i++){
    70         scanf("%d",&a);
    71         for(int j=1;j<=a;j++){
    72             scanf("%d",&b);
    73             rnum[b]++;
    74             aa[b][rnum[b]]=i;
    75         }
    76         scanf("%d",&a);
    77         mnum[i]=a;
    78     }
    79     for(int i=1;i<=m;i++){
    80         add(S,aa[i][1],numm[i]);
    81         for(int j=1;j<rnum[i];j++)
    82             add(aa[i][j],aa[i][j+1],INF);
    83     }
    84     for(int i=1;i<=n;i++)
    85         add(i,T,mnum[i]);
    86     printf("%d",dinic());
    87     return 0;
    88 }
  • 相关阅读:
    使用文件进行数据存储四种模式
    文件保存与读取
    查看与输出日志信息
    单元测试
    短信发送器
    简易的安卓拨号器
    Android manifest之manifest标签详细介绍
    Python实现不同格式打印九九乘法表
    Java-JDK & Android SDK下载安装及配置教程
    Django modelfrom
  • 原文地址:https://www.cnblogs.com/dugudashen/p/6243305.html
Copyright © 2011-2022 走看看