• [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
  • 相关阅读:
    sge的简单的应用
    dcoker 小应用(二)
    浅谈Docker(二)
    查看Linux版本
    dcoker 小应用(一)
    linux 强制重启!
    浅谈Docker(一)
    ubuntu command
    简析hotjar录屏功能实现原理
    实现node端渲染图表的简单方案
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249590.html
Copyright © 2020-2023  润新知