bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
2016-03-16 16:49
253 查看
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1834
【题意】
给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最少扩容费用。
【思路】
第一问就是费用为0的费用流
第二问在第一问的残量网络上操作,对于每条边都新加一条容量为inf,且费用为W的边。至于容量增加K,只要新建一个S点向1连一条容量为K费用为0的边即可。然后跑一遍最小费用最大流。
【代码】
http://www.lydsy.com/JudgeOnline/problem.php?id=1834
【题意】
给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最少扩容费用。
【思路】
第一问就是费用为0的费用流
第二问在第一问的残量网络上操作,对于每条边都新加一条容量为inf,且费用为W的边。至于容量增加K,只要新建一个S点向1连一条容量为K费用为0的边即可。然后跑一遍最小费用最大流。
【代码】
#include<set> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) #define FOR(a,b,c) for(int a=(b);a<=(c);a++) using namespace std; typedef long long ll; const int N = 1e3+10; const int inf = 2e9; ll read() { char c=getchar(); ll f=1,x=0; while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } struct Edge { int u,v,cap,flow,cost,t; }; struct MCMF { int n,m,s,t; int a ,inq ,d ,p ; queue<int> q; vector<Edge> es; vector<int> g ; void init(int n) { this->n=n; es.clear(); for(int i=0;i<=n;i++) g[i].clear(); } void AddEdge(int u,int v,int w,int c,int f) { es.push_back((Edge){u,v,w,0,f*c,c}); es.push_back((Edge){v,u,0,0,-f*c,c}); int m=es.size(); g[u].push_back(m-2); g[v].push_back(m-1); } bool spfa(int s,int t,int& flow,int& cost) { memset(inq,0,sizeof(inq)); for(int i=0;i<=n;i++) d[i]=inf; q.push(s); inq[s]=1,a[s]=inf,d[s]=0; while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; for(int i=0;i<g[u].size();i++) { Edge& e=es[g[u][i]]; int v=e.v; if(e.cap>e.flow && d[v]>d[u]+e.cost) { d[v]=d[u]+e.cost; p[v]=g[u][i]; a[v]=min(a[u],e.cap-e.flow); if(!inq[v]) inq[v]=1, q.push(v); } } } if(d[t]==inf) return 0; flow+=a[t],cost+=a[t]*d[t]; for(int x=t;x!=s;x=es[p[x]].u) { es[p[x]].flow+=a[t]; es[p[x]^1].flow-=a[t]; } return 1; } void mcmf(int s,int t,int& flow,int& cost) { flow=cost=0; while(spfa(s,t,flow,cost)) ; } } mc; int n,m,K; int main() { n=read(),m=read(),K=read(); mc.init(n+3); int S=0,T=n; int u,v,w,c; FOR(i,1,m) { u=read(),v=read(),w=read(),c=read(); mc.AddEdge(u,v,w,c,0); } int flow,cost; mc.mcmf(1,n,flow,cost); printf("%d ",flow); int mx=mc.es.size(); for(int i=0;i<mx;i+=2) { Edge e=mc.es[i]; mc.AddEdge(e.u,e.v,inf,e.t,1); } mc.AddEdge(S,1,K,0,1); mc.mcmf(S,T,flow,cost); printf("%d",cost); return 0; }
相关文章推荐
- HTTP详解
- 基于http live streaming, 使用vlc + mediastreamsegmenter + apache 实现iOS视频直播
- iOS网络3—UIWebView与WKWebView使用详解
- 编写天气Demo,接触OKhttp框架,框架没那么难
- Java网络编程(二)总结
- iOS之网络编程
- HTTP和HTTPS的区别
- keras:保存keras学习好的深度神经网络模型参数为二进制和txt文件
- TCP/UDP网络编程
- 网络编程释疑之:同步,异步,阻塞,非阻塞
- iOS 判断有无网络连接
- C#和java和android中的NetWorkAdapter,httpRequest,WebView,json,xml
- httplib-Python
- android中进行https连接的方式
- tomcat7+jdk的keytool生成证书 配置https
- netstat命令---输出网络相关的信息
- C# HttpWebReqeust和HttpWebResponse发送请求
- TCP协议疑难杂症全景解析
- XSS漏洞修补及预防--使用过滤器
- iOS上传文件到服务器(ASIHttpRequest)