• [网络流24题] 运输问题 (费用流)


    洛谷传送门 LOJ传送门

    分配问题这题的建图一模一样啊...这题只不过是多了个流量限制

    首先题目保证货物总量和仓库容量相等,考虑最大流

    源点$S$向每个仓库连流量为$a_{i}$,费用为$0$的边,每个商店向汇点连流量为$b_{i}$,费用为$0$的边,代表货物总量和商店容量

    由于仓库可以向商店随便运货,只要仓库有足够多货且商店能装下就行,所以每个仓库$i$和每个商店$j$之间连一条流量为$inf$,费用为$c_{i,j}$的边

    然后上费用流就行了

      1 #include <vector>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define N1 205
      6 #define M1 50010
      7 #define ll long long
      8 #define dd double
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 
     12 int gint()
     13 {
     14     int ret=0,fh=1;char c=getchar();
     15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     17     return ret*fh;
     18 }
     19 
     20 int n,m,nm,S,T;
     21 int flow[N1][N1],cost[N1][N1],f[N1][N1],c[N1][N1];
     22 int que[M1],hd,tl,C[N1],F[N1],pre[N1];
     23 
     24 namespace S1{
     25 void bfs()
     26 {
     27     int x,i,v;
     28     memset(C,0x3f,sizeof(C)); memset(F,0,sizeof(F)); 
     29     hd=1,tl=0; que[++tl]=S; C[S]=0; F[S]=inf;
     30     while(hd<=tl)
     31     {
     32         x=que[hd++];
     33         for(v=1;v<=nm;v++)
     34         {
     35             if(!flow[x][v]) continue; 
     36             if(C[v]>C[x]+cost[x][v]) 
     37             {
     38                 C[v]=C[x]+cost[x][v];
     39                 F[v]=min(F[x],flow[x][v]);
     40                 que[++tl]=v; pre[v]=x;
     41             }
     42         }
     43     }
     44 } 
     45 void Dinic()
     46 {
     47     memcpy(cost,c,sizeof(c)); memcpy(flow,f,sizeof(f));
     48     int cash=0,tmp,x;
     49     while(1)
     50     {
     51         bfs(); if(!F[T]) break;
     52         for(x=T;x!=S;x=pre[x]) 
     53             flow[pre[x]][x]-=F[T],flow[x][pre[x]]+=F[T];
     54         cash+=C[T]*F[T];
     55     }
     56     printf("%d
    ",cash);
     57 }
     58 };
     59 
     60 namespace S2{
     61 void bfs()
     62 {
     63     int x,v;
     64     memset(C,-0x3f,sizeof(C)); memset(F,0,sizeof(F)); 
     65     hd=1,tl=0; que[++tl]=S; C[S]=0; F[S]=inf;
     66     while(hd<=tl)
     67     {
     68         x=que[hd++];
     69         for(v=1;v<=nm;v++)
     70         {
     71             if(!flow[x][v]) continue; 
     72             if(C[v]<C[x]+cost[x][v]) 
     73             {
     74                 C[v]=C[x]+cost[x][v];
     75                 F[v]=min(F[x],flow[x][v]);
     76                 que[++tl]=v; pre[v]=x;
     77             }
     78         }
     79     }
     80 } 
     81 void Dinic()
     82 {
     83     memcpy(cost,c,sizeof(c)); memcpy(flow,f,sizeof(f));
     84     int cash=0,tmp,x;
     85     while(1)
     86     {
     87         bfs(); if(!F[T]) break;
     88         for(x=T;x!=S;x=pre[x]) 
     89             flow[pre[x]][x]-=F[T],flow[x][pre[x]]+=F[T];
     90         cash+=C[T]*F[T];
     91     }
     92     printf("%d
    ",cash);
     93 }
     94 };
     95 
     96 int a[N1],b[N1];
     97 
     98 int main()
     99 {
    100     scanf("%d%d",&m,&n); nm=n+m+2;
    101     int i,j,v,ans; S=n+m+1,T=n+m+2;
    102     for(i=1;i<=m;i++) scanf("%d",&a[i]), f[S][i]=a[i], c[S][i]=0;
    103     for(i=m+1;i<=m+n;i++) scanf("%d",&b[i]), f[i][T]=b[i], c[i][T]=0;
    104     for(i=1;i<=m;i++) for(j=m+1;j<=m+n;j++) 
    105         scanf("%d",&c[i][j]),c[j][i]=-c[i][j], f[i][j]=inf, f[j][i]=0;
    106     S1::Dinic(); S2::Dinic(); 
    107     return 0;
    108 }
  • 相关阅读:
    匿名字段和内嵌结构体
    Go函数式编程的闭包和装饰器设计模式
    理解Golang中defer的使用
    Go匿名函数及闭包
    GO语言学习笔记-缓冲区Channels和线程池
    你需要知道的关于Neutron的一切事情
    []T 还是 []*T, 这是一个问题
    Golang 方法接收者为值与指针的区别
    第九章 python语法入门之与用户交互、运算符
    第八章 python语法入门之垃圾回收机制
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10283933.html
Copyright © 2020-2023  润新知