• [bzoj1711]吃饭


    由于无法直接将果汁和饮料连边,所以将人放在中间,果汁和饮料放在两侧,然后分别向对应的人连边。同时,为了保证每一个人只被算一次,对每一个人裂点,两个点中间连一条流量为1的边。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 505
     4 #define inf 0x3f3f3f3f
     5 struct ji{
     6     int nex,to,len;
     7 }edge[N*N];
     8 queue<int>q;
     9 int E,n,x,y,k1,k2,p,d[N],head[N],work[N];
    10 void add(int x,int y,int z){
    11     edge[E].nex=head[x];
    12     edge[E].to=y;
    13     edge[E].len=z;
    14     head[x]=E++;
    15     if (E&1)add(y,x,0); 
    16 }
    17 bool bfs(){
    18     q.push(0);
    19     memset(d,-1,sizeof(d));
    20     d[0]=0;
    21     while (!q.empty()){
    22         int k=q.front();
    23         q.pop();
    24         for(int i=head[k];i!=-1;i=edge[i].nex)
    25             if ((edge[i].len)&&(d[edge[i].to]<0)){
    26                 d[edge[i].to]=d[k]+1;
    27                 q.push(edge[i].to);
    28             }
    29     }
    30     return d[n]>=0;
    31 }
    32 int dfs(int k,int s){
    33     if (k==n)return s;
    34     int p;
    35     for(int &i=work[k];i!=-1;i=edge[i].nex)
    36         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    37             p=dfs(edge[i].to,min(s,edge[i].len));
    38             if (p){
    39                 edge[i].len-=p;
    40                 edge[i^1].len+=p;
    41                 return p;
    42             }
    43         }
    44     return 0;
    45 }
    46 int dinic(){
    47     int k,ans=0;
    48     while (bfs()){
    49         memcpy(work,head,sizeof(work));
    50         while (k=dfs(0,inf))ans+=k;
    51     }
    52     return ans;
    53 }
    54 int main(){
    55     scanf("%d%d%d",&n,&x,&y);
    56     memset(head,-1,sizeof(head));
    57     for(int i=1;i<=x;i++)add(0,i,1);
    58     for(int i=1;i<=n;i++){
    59         scanf("%d%d",&k1,&k2);
    60         for(int j=1;j<=k1;j++){
    61             scanf("%d",&p);
    62             add(p,x+i,1);
    63         }
    64         add(x+i,n+x+i,1);
    65         for(int j=1;j<=k2;j++){
    66             scanf("%d",&p);
    67             add(n+x+i,2*n+x+p,1);
    68         }
    69     }
    70     n=2*n+x;
    71     for(int i=n+1;i<=n+y;i++)add(i,n+y+1,1);
    72     n+=y+1;
    73     printf("%d",dinic());
    74 }
    View Code
  • 相关阅读:
    b_jd_水坑数量(向外流dfs)
    b_wy_购买商品使得满减最省(01背包)
    b_wy_最优路径(构造树+dfs)
    Redis:List列表相关指令
    Redis:String字符串常用指令
    Redis:linux基本的指令
    Redis:redis-benchmark性能测试/压力测试
    Redis:增大并发量的演进过程
    Kafka的下载安装和测试,及消费端数据中文乱码问题
    Git:常用命令
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249609.html
Copyright © 2020-2023  润新知