bzoj1834
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。
求:
1、在不扩容的情况下,1到N的最大流;
2、将1到N的最大流增加K所需的最小扩容费用。
Input
第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。
接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
N<=1000,M<=5000,K<=10
Output
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
先按每条费用为0,容量为c跑费用流求最大流量,然后对原图中每条边建一条容量inf,费用为w的边,新建超级源和1连边,容量k,费用0,
因为要保证流量增加k,而且原图中的边是没有费用的,而只要增加 了费用,流量一定够,所以设成inf
/************************************************************** ???Problem: 1834 ???User: walfy ???Language: C++ ???Result: Accepted ???Time:112 ms ???Memory:2720 kb****************************************************************/ //#pragma comment(linker, "/stack:200000000")//#pragma GCC optimize("Ofast,no-stack-protector")//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")//#pragma GCC optimize("unroll-loops")#include<bits/stdc++.h>#define fi first#define se second#define mp make_pair#define pb push_back#define pi acos(-1.0)#define ll long long#define vi vector<int>#define mod 1000000007#define ld long double#define C 0.5772156649#define ls l,m,rt<<1#define rs m+1,r,rt<<1|1#define pil pair<int,ll>#define pli pair<ll,int>#define pii pair<int,int>#define cd complex<double>#define ull unsigned long long#define base 1000000000000000000#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double eps=1e-6;const int N=20000+10,maxn=50000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct edge{ ???int to,Next,c; ???int cost;}e[maxn];int cnt,head[N];int s,t;int dis[N],pre[N],path[N];bool vis[N];void add(int u,int v,int c,int cost){ ???e[cnt].to=v; ???e[cnt].c=c; ???e[cnt].cost=cost; ???e[cnt].Next=head[u]; ???head[u]=cnt++; ???e[cnt].to=u; ???e[cnt].c=0; ???e[cnt].cost=-cost; ???e[cnt].Next=head[v]; ???head[v]=cnt++;}bool spfa(){ ???memset(pre,-1,sizeof pre); ???memset(dis,inf,sizeof dis); ???memset(vis,0,sizeof vis); ???dis[s]=0; ???vis[s]=1; ???queue<int>q; ???q.push(s); ???while(!q.empty()) ???{ ???????int x=q.front(); ???????q.pop(); ???????vis[x]=0; ???????for(int i=head[x];~i;i=e[i].Next) ???????{ ???????????int te=e[i].to; ???????????if(e[i].c>0&&dis[x]+e[i].cost<dis[te]) ???????????{ ???????????????dis[te]=dis[x]+e[i].cost; ???????????????pre[te]=x; ???????????????path[te]=i; ???????????????if(!vis[te])q.push(te),vis[te]=1; ???????????} ???????} ???} ???return pre[t]!=-1;}int maxflow(){ ???int flow=0; ???while(spfa()) ???{ ???????int f=inf; ???????for(int i=t;i!=s;i=pre[i]) ???????????if(e[path[i]].c<f) ??????????????f=e[path[i]].c; ???????flow+=f; ???????for(int i=t;i!=s;i=pre[i]) ???????{ ???????????e[path[i]].c-=f; ???????????e[path[i]^1].c+=f; ???????} ???} ???return flow;}int mincostmaxflow(){ ???int cost=0,flow=0; ???while(spfa()) ???{ ???????int f=inf; ???????for(int i=t;i!=s;i=pre[i]) ???????????if(e[path[i]].c<f) ??????????????f=e[path[i]].c; ???????flow+=f; ???????cost+=dis[t]*f; ???????for(int i=t;i!=s;i=pre[i]) ???????{ ???????????e[path[i]].c-=f; ???????????e[path[i]^1].c+=f; ???????} ???} ???return cost;}void init(){ ???memset(head,-1,sizeof head); ???cnt=0;}struct node{int u,v,c,w;}te[N];int main(){ ???int n,m,k; ???scanf("%d%d%d",&n,&m,&k); ???init(); ???for(int i=0;i<m;i++) ???{ ???????int u,v,c,w; ???????scanf("%d%d%d%d",&u,&v,&c,&w); ???????add(u,v,c,0); ???????te[i]={u,v,c,w}; ???} ???s=1,t=n; ???printf("%d ",maxflow()); ???for(int i=0;i<m;i++) ???????add(te[i].u,te[i].v,inf,te[i].w); ???s=n+1;add(s,1,k,0); ???printf("%d\n",mincostmaxflow()); ???return 0;}/******************** ********************/
bzoj1834: [ZJOI2010]network 网络扩容 ??费用流
原文地址:https://www.cnblogs.com/acjiumeng/p/9302117.html