BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)

挺直白的构图。。最小费用最大流的定义。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<algorithm>
  5 using namespace std;
  6 #define INF (1<<30)
  7 #define MAXN 11111
  8 #define MAXM 2222222
  9 struct Edge{
 10     int u,v,cap,cost,next;
 11 }edge[MAXM];
 12 int head[MAXN];
 13 int NV,NE,vs,vt;
 14 
 15 void addEdge(int u,int v,int cap,int cost){
 16     edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
 17     edge[NE].next=head[u]; head[u]=NE++;
 18     edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
 19     edge[NE].next=head[v]; head[v]=NE++;
 20 }
 21 bool vis[MAXN];
 22 int d[MAXN],pre[MAXN];
 23 bool SPFA(){
 24     for(int i=0;i<NV;++i){
 25         vis[i]=0;
 26         d[i]=INF;
 27     }
 28     vis[vs]=1;
 29     d[vs]=0;
 30     queue<int> que;
 31     que.push(vs);
 32     while(!que.empty()){
 33         int u=que.front(); que.pop();
 34         for(int i=head[u]; i!=-1; i=edge[i].next){
 35             int v=edge[i].v;
 36             if(edge[i].cap && d[v]>d[u]+edge[i].cost){
 37                 d[v]=d[u]+edge[i].cost;
 38                 pre[v]=i;
 39                 if(!vis[v]){
 40                     vis[v]=1;
 41                     que.push(v);
 42                 }
 43             }
 44         }
 45         vis[u]=0;
 46     }
 47     return d[vt]!=INF;
 48 }
 49 int MCMF(){
 50     int res=0;
 51     while(SPFA()){
 52         int flow=INF,cost=0;
 53         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 54             flow=min(flow,edge[pre[u]].cap);
 55         }
 56         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 57             edge[pre[u]].cap-=flow;
 58             edge[pre[u]^1].cap+=flow;
 59             cost+=flow*edge[pre[u]].cost;
 60         }
 61         res+=cost;
 62     }
 63     return res;
 64 }
 65 int MF(){
 66     int res=0;
 67     while(SPFA()){
 68         int flow=INF,cost=0;
 69         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 70             flow=min(flow,edge[pre[u]].cap);
 71         }
 72         res+=flow;
 73         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 74             edge[pre[u]].cap-=flow;
 75             edge[pre[u]^1].cap+=flow;
 76         }
 77     }
 78     return res;
 79 }
 80 int u[MAXN],v[MAXN],c[MAXN],w[MAXN];
 81 int main(){
 82     int n,m,k;
 83     scanf("%d%d%d",&n,&m,&k);
 84     vs=1; vt=n; NV=vt+1; NE=0;
 85     memset(head,-1,sizeof(head));
 86     for(int i=0; i<m; ++i){
 87         scanf("%d%d%d%d",u+i,v+i,c+i,w+i);
 88         addEdge(u[i],v[i],c[i],1);
 89     }
 90     int mxflow=MF();
 91     printf("%d ",mxflow);
 92     vs=1; vt=0; NV=n+1; NE=0;
 93     memset(head,-1,sizeof(head));
 94     addEdge(n,vt,mxflow+k,0);
 95     for(int i=0; i<m; ++i){
 96         addEdge(u[i],v[i],c[i],0);
 97         addEdge(u[i],v[i],INF,w[i]);
 98     }
 99     printf("%d",MCMF());
100     return 0;
101 }
原文地址:https://www.cnblogs.com/WABoss/p/5325720.html