【BZOJ1834】网络扩容(最大流,费用流)
2017-12-29 10:48
176 查看
题面
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 21 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 1930%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
题解
第一问裸的最大流第二问
把原来的边的费用视为0
扩容的话就
4000
额外连一条容量为INF,费用为W的边
因为限制K流量
S向1连容量为K,费用为0的边
其实没必要把图推到重建
原来跑最大流的时候就流满了流了
反正费用都是0,与第二问不影响
直接加边就行了
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define MAXL 1000000 #define MAX 100000 #define INF 1000000000 inline int read() { int x=0,t=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } struct Line { int v,next,w,fy; }e[MAXL]; int U[MAX],V[MAX],C[MAX],W[MAX]; int h[MAX],cnt; int ans,S,T,n,m; inline void Add(int u,int v,int w,int fy) { e[cnt]=(Line){v,h[u],w,fy}; h[u]=cnt++; e[cnt]=(Line){u,h[v],0,-fy}; h[v]=cnt++; } int level[MAX]; bool BFS() { memset(level,0,sizeof(level)); level[S]=1; queue<int> Q; Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&!level[v]) level[v]=level[u]+1,Q.push(v); } } return level[T]; } int DFS(int u,int flow) { if(flow==0||u==T)return flow; int ret=0; for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&level[v]==level[u]+1) { int dd=DFS(v,min(flow,e[i].w)); flow-=dd;ret+=dd; e[i].w-=dd;e[i^1].w+=dd; } } return ret; } int Dinic() { int ret=0; while(BFS())ret+=DFS(S,INF); return ret; } bool vis[MAX]; int dis[MAX],pe[MAX],pr[MAX],Cost; int K; bool SPFA() { for(int i=1;i<=T;++i)dis[i]=INF; queue<int> Q;Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=h[u];i!=-1;i=e[i].next) { int v=e[i].v; if(e[i].w&&dis[v]>dis[u]+e[i].fy) { dis[v]=dis[u]+e[i].fy; pe[v]=i;pr[v]=u; if(!vis[v])vis[v]=true,Q.push(v); } } vis[u]=false; } if(dis[T]==INF)return false; int flow=INF; for(int i=T;i!=S;i=pr[i])flow=min(flow,e[pe[i]].w); for(int i=T;i!=S;i=pr[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow; Cost+=flow*dis[T]; return true; } int main() { memset(h,-1,sizeof(h)); n=read();m=read();K=read(); S=1;T=n; for(int i=1;i<=m;++i) { U[i]=read();V[i]=read();C[i]=read();W[i]=read(); Add(U[i],V[i],C[i],0); } int G; printf("%d ",G=Dinic()); S=0;T=n;Add(S,1,K,0); for(int i=1;i<=m;++i)Add(U[i],V[i],K,W[i]); while(SPFA()); printf("%d\n",Cost); return 0; }
相关文章推荐
- 【BZOJ1834】【codevs1362】网络扩容,最大流+费用流
- 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容
- BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】
- [BZOJ1834]ZJOI2010网络扩容|最大流|费用流
- 【BZOJ1834】network 网络扩容(最大流,费用流)
- [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流
- bzoj1834 [ZJOI2010]network 网络扩容 最大流+费用流
- [bzoj1834][ZJOI2010] 网络扩容 最大流 费用流
- bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流
- 【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容
- BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞
- 【bzoj1834】[ZJOI2010]network 网络扩容 费用流
- bzoj 1834 [ZJOI2010] network 网络扩容(费用流)
- 【bzoj1834】[ZJOI2010]network 网络扩容 最大流+最小费用流
- bzoj 1834 网络扩容 (费用流)
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
- bzoj1834 [ZJOI2010]network 网络扩容(费用流)
- BZOJ_1834_[ZJOI2010]network 网络扩容_费用流
- [ZJOI2010][bzoj1834] 网络扩容 [费用流]
- BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)