【BZOJ 1834】 [ZJOI2010]network 网络扩容
2015-04-19 09:01
337 查看
1834: [ZJOI2010]network 网络扩容
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1891 Solved: 937
[Submit][Status][Discuss]
Description
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。
Input
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
Output
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
Sample Input
5 8 2
1 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1
Sample Output
13 19 30%的数据中,N<=100 100%的数据中,N<=1000,M<=5000,K<=10
HINT
Source
Day1
最大流+费用流
第一问是最大流模板;
第二问:我们在第一问的残量网络中建立费用流模型,从s到1连流量为k,费用为0的边,并对原图中的每一条边再连上费用为wiw_i流量为inf的边,然后跑费用流即可。
#include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <cstdio> #define M 1005 #define inf 0x3f3f3f3f using namespace std; int tot=1,k,n,m,cur[M],h[M],v[M],d[M],inq[M],p[M],a[M]; struct READ { int u,v,c,w; }r[M*5]; struct edge { int from,to,cap,flow,cost,ne; }E[200005]; void Addedge(int from,int to,int cap,int cost) { E[++tot]=(edge){from,to,cap,0,cost,h[from]}; h[from]=tot; E[++tot]=(edge){to,from,0,0,-cost,h[to]}; h[to]=tot; } int bfs() { for (int i=1;i<=n;i++) v[i]=0; queue<int> q; q.push(1); v[1]=1; d[1]=0; while (!q.empty()) { int x=q.front(); q.pop(); for (int i=h[x];i;i=E[i].ne) { edge e=E[i]; if (e.cap>e.flow&&!v[e.to]) { v[e.to]=1; d[e.to]=d[x]+1; q.push(e.to); } } } return v ; } int dfs(int x,int a) { if (x==n||!a) return a; int flow=0; for (int &i=cur[x];i;i=E[i].ne) { edge &e=E[i]; if (d[e.to]!=d[x]+1) continue; int f=dfs(e.to,min(a,e.cap-e.flow)); if (f) { a-=f; e.flow+=f; E[i^1].flow-=f; flow+=f; if (!a) break; } } return flow; } int dinic() { int flow=0; while (bfs()) { for (int i=1;i<=n;i++) cur[i]=h[i]; flow+=dfs(1,inf); } return flow; } int spfa(int &flow,int &cost) { for (int i=0;i<=n;i++) d[i]=inf,inq[i]=0; queue<int> q; q.push(0); inq[0]=1,d[0]=0,a[0]=inf,p[0]=0; while (!q.empty()) { int x=q.front(); q.pop(); inq[x]=0; for (int i=h[x];i;i=E[i].ne) { edge e=E[i]; if (d[e.to]>d[x]+e.cost&&e.cap>e.flow) { d[e.to]=d[x]+e.cost; p[e.to]=i; a[e.to]=min(a[x],e.cap-e.flow); if (!inq[e.to]) q.push(e.to),inq[e.to]=1; } } } if (d ==inf) return 0; flow+=a ; cost+=a *d ; int x=n; while (x) { int y=p[x]; E[y].flow+=a ; E[y^1].flow-=a ; x=E[y].from; } return 1; } int mincost() { int flow=0,cost=0; while (spfa(flow,cost)); return cost; } int main() { scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=m;i++) { scanf("%d%d%d%d",&r[i].u,&r[i].v,&r[i].c,&r[i].w); Addedge(r[i].u,r[i].v,r[i].c,0); } printf("%d",dinic()); Addedge(0,1,k,0); for (int i=1;i<=m;i++) Addedge(r[i].u,r[i].v,inf,r[i].w); printf(" %d\n",mincost()); return 0; }
相关文章推荐
- bzoj1834 [ZJOI2010]network 网络扩容(费用流)
- BZOJ 1834: [ZJOI2010]network 网络扩容
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容 最大流+费用流
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
- 【bzoj1834】[ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容
- BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】
- BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
- [BZOJ1834][ZJOI2010]network 网络扩容(最大流+费用流)
- bzoj 1834: [ZJOI2010]network 网络扩容(isap+费用流)
- 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流
- [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流
- bzoj1834: [ZJOI2010]network 网络扩容
- 【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容
- [BZOJ1834][ZJOI2010]network 网络扩容
- BZOJ1834 [ZJOI2010]network 网络扩容
- BZOJ 1834 【ZJOI2010】 network 网络扩容
- bzoj1834[ZJOI2010]network 网络扩容【最大流+费用流】
- 【bzoj1834】[ZJOI2010]network 网络扩容