博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1834: [ZJOI2010]network 网络扩容 最小费用流_最大流_残量网络
阅读量:5276 次
发布时间:2019-06-14

本文共 2496 字,大约阅读时间需要 8 分钟。

对于第一问,跑一遍最大流即可.

对于第二问,在残量网络上的两点间建立边 <u,v>,容量为无限大,费用为扩充费用.

跑一遍最小费用流即可.

Code:

#include 
#include
#include
#include
#include
#define setIO(s) freopen(s".in","r",stdin) #define inf 100000000 #define maxn 100000 #define ll long long using namespace std;struct Edges{ int u,v,c,w; }EDGE[maxn]; int n,m,k,s,t; struct Edge{ int from,to,cap,cost; Edge(int u,int v,int c,int f) : from(u),to(v),cap(c),cost(f){} }; vector
G[maxn]; vector
edges; void addedge(int u,int v,int c,int f){ edges.push_back(Edge(u,v,c,f)); edges.push_back(Edge(v,u,0,-f)); int o = edges.size(); G[u].push_back(o - 2); G[v].push_back(o - 1); }namespace Dinic{ int d[maxn],vis[maxn]; queue
Q; int BFS(){ memset(vis,0,sizeof(vis)); vis[s] = 1,d[s] = 0; Q.push(s); while(!Q.empty()){ int u = Q.front(); Q.pop(); int sz = G[u].size(); for(int i=0;i
0) { d[r.to] = d[u] + 1; vis[r.to] = 1; Q.push(r.to); } } } return vis[t]; } int current[maxn]; int DFS(int x,int cur){ if(x==t) return cur; int flow=0,f; int sz = G[x].size(); for(int i=current[x];i
0){ f = DFS(r.to,min(cur,r.cap)); if(f > 0) { flow += f; cur -= f; edges[u].cap -= f; edges[u^1].cap += f; } } if(cur==0) break; } return flow; } int maxflow(){ int flow=0; while(BFS()){ memset(current,0,sizeof(current)); flow += DFS(s,inf); } return flow; }}; namespace MCMF{ queue
Q; int d[maxn],inq[maxn]; int flow2[maxn],a[maxn]; long long ans; int SPFA(){ for(int i=0;i
0 && d[r.to] > d[u] + r.cost) { d[r.to] = d[u] + r.cost; a[r.to] = G[u][i]; flow2[r.to] = min(flow2[u],r.cap); if(!inq[r.to]) { inq[r.to] = 1; Q.push(r.to); } } } } if(flow2[t] == inf) return 0; int f = flow2[t]; edges[a[t]].cap -= f, edges[a[t] ^ 1].cap += f; int u = edges[a[t]].from; while(u != s){ edges[a[u]].cap -= f; edges[a[u]^1].cap += f; u = edges[a[u]].from; } ans += (ll)(d[t] * f); return 1; } long long getcost(){ while(SPFA()); return ans; } }; int main(){ //setIO("input"); scanf("%d%d%d",&n,&m,&k); s = 1, t = n; for(int i = 1;i <= m; ++i) scanf("%d%d%d%d",&EDGE[i].u,&EDGE[i].v,&EDGE[i].c,&EDGE[i].w); for(int i = 1;i <= m; ++i) addedge(EDGE[i].u,EDGE[i].v,EDGE[i].c,0); printf("%d ",Dinic::maxflow()); for(int i = 1;i <= m; ++i) addedge(EDGE[i].u,EDGE[i].v,inf,EDGE[i].w); s = 0 , t = n + 1; addedge(s,1,k,0); addedge(n,n+1,k,0); printf("%lld",MCMF::getcost()); return 0; }

  

转载于:https://www.cnblogs.com/guangheli/p/10658906.html

你可能感兴趣的文章
Java 序列化
查看>>
Java 时间处理实例
查看>>
Java 多线程编程
查看>>
Java 数组实例
查看>>
mysql启动过程
查看>>
2017前端面试题总结
查看>>
Http GetPost网络请求
查看>>
SWIFT国际资金清算系统
查看>>
Sping注解:注解和含义
查看>>
站立会议第四天
查看>>
如何快速掌握一门技术
查看>>
利用AMPScript获取Uber用户数据的访问权限
查看>>
vagrant 同时设置多个同步目录
查看>>
python接口自动化28-requests-html爬虫框架
查看>>
生成随机数的模板
查看>>
Mysql 数据库操作
查看>>
转:linux终端常用快捷键
查看>>
UVa 11059 最大乘积
查看>>
数组分割问题求两个子数组的和差值的小
查看>>
composer 报 zlib_decode(): data error
查看>>