bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1834
【题意】
给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最少扩容费用。
【思路】
第一问就是费用为0的费用流
第二问在第一问的残量网络上操作,对于每条边都新加一条容量为inf,且费用为W的边。至于容量增加K,只要新建一个S点向1连一条容量为K费用为0的边即可。然后跑一遍最小费用最大流。
【代码】
1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 11 using namespace std; 12 13 typedef long long ll; 14 const int N = 1e3+10; 15 const int inf = 2e9; 16 17 ll read() { 18 char c=getchar(); 19 ll f=1,x=0; 20 while(!isdigit(c)) { 21 if(c=='-') f=-1; c=getchar(); 22 } 23 while(isdigit(c)) 24 x=x*10+c-'0',c=getchar(); 25 return x*f; 26 } 27 28 struct Edge { int u,v,cap,flow,cost,t; 29 }; 30 31 struct MCMF { 32 int n,m,s,t; 33 int a[N],inq[N],d[N],p[N]; 34 queue<int> q; 35 vector<Edge> es; 36 vector<int> g[N]; 37 void init(int n) { 38 this->n=n; 39 es.clear(); 40 for(int i=0;i<=n;i++) g[i].clear(); 41 } 42 void AddEdge(int u,int v,int w,int c,int f) { 43 es.push_back((Edge){u,v,w,0,f*c,c}); 44 es.push_back((Edge){v,u,0,0,-f*c,c}); 45 int m=es.size(); 46 g[u].push_back(m-2); 47 g[v].push_back(m-1); 48 } 49 bool spfa(int s,int t,int& flow,int& cost) { 50 memset(inq,0,sizeof(inq)); 51 for(int i=0;i<=n;i++) d[i]=inf; 52 q.push(s); 53 inq[s]=1,a[s]=inf,d[s]=0; 54 while(!q.empty()) { 55 int u=q.front(); q.pop(); 56 inq[u]=0; 57 for(int i=0;i<g[u].size();i++) { 58 Edge& e=es[g[u][i]]; 59 int v=e.v; 60 if(e.cap>e.flow && d[v]>d[u]+e.cost) { 61 d[v]=d[u]+e.cost; 62 p[v]=g[u][i]; 63 a[v]=min(a[u],e.cap-e.flow); 64 if(!inq[v]) 65 inq[v]=1, 66 q.push(v); 67 } 68 } 69 } 70 if(d[t]==inf) return 0; 71 flow+=a[t],cost+=a[t]*d[t]; 72 for(int x=t;x!=s;x=es[p[x]].u) { 73 es[p[x]].flow+=a[t]; 74 es[p[x]^1].flow-=a[t]; 75 } 76 return 1; 77 } 78 void mcmf(int s,int t,int& flow,int& cost) { 79 flow=cost=0; 80 while(spfa(s,t,flow,cost)) ; 81 } 82 } mc; 83 84 int n,m,K; 85 86 int main() 87 { 88 n=read(),m=read(),K=read(); 89 mc.init(n+3); 90 int S=0,T=n; 91 int u,v,w,c; 92 FOR(i,1,m) { 93 u=read(),v=read(),w=read(),c=read(); 94 mc.AddEdge(u,v,w,c,0); 95 } 96 int flow,cost; 97 mc.mcmf(1,n,flow,cost); 98 printf("%d ",flow); 99 int mx=mc.es.size(); 100 for(int i=0;i<mx;i+=2) { 101 Edge e=mc.es[i]; 102 mc.AddEdge(e.u,e.v,inf,e.t,1); 103 } 104 mc.AddEdge(S,1,K,0,1); 105 mc.mcmf(S,T,flow,cost); 106 printf("%d",cost); 107 return 0; 108 }
posted on 2016-03-16 16:49 hahalidaxin 阅读(238) 评论(0) 编辑 收藏 举报