zoukankan      html  css  js  c++  java
  • [bzoj1280]卖猪

    首先考虑猪无法流动,那么源点向每一个猪圈连猪圈中猪个数的边,每一个顾客向汇点连所需猪的边,每一个猪圈向能打开它的顾客连inf的边,跑最大流即可。

    但考虑猪要流动,有一个十分巧妙地做法,将每一个顾客所有有公共猪圈的顾客连inf的边,同时每一个猪圈只连向第一次打开它的顾客(也可以流向所有顾客,不过没必要),这样就可以解决了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 2001
     4 #define inf 0x3f3f3f3f
     5 struct ji{
     6     int nex,to,len;
     7 }edge[N*20];
     8 queue<int>q;
     9 int E,n,m,p,k,id[N],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",&m,&n);
    56     memset(head,-1,sizeof(head));
    57     for(int i=1;i<=m;i++){
    58         scanf("%d",&p);
    59         add(0,i,p);
    60         id[i]=i;
    61     }
    62     for(int i=1;i<=n;i++){
    63         scanf("%d",&k);
    64         for(int j=1;j<=k;j++){
    65             scanf("%d",&p);
    66             add(id[p],m+i,inf);
    67             id[p]=m+i;
    68         }
    69         scanf("%d",&p);
    70         add(m+i,n+m+1,p);
    71     }
    72     n+=m+1;
    73     printf("%d",dinic());
    74 }
    View Code
  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249590.html
Copyright © 2011-2022 走看看