题目描述
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。
输入输出格式
输入格式:
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
输出格式:
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
输入输出样例
说明
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
给自己加个油,1A。
说一下大致思路。
对于第一问,很简单就是求个最大流F。但是第二问呢?
我们可以这样想,第一问建的边相当于是花费为0,(流量该是多少就是多少)的边
对于有扩容费用的边,就相当于是花费为扩容费用,流量为?的边。
题目中要求将1-n的流量增加k,即限制1-n的最大流为F+k。
那么我们就想办法找一条边来限制F+k这个流量,也就是说其他的边不能够成为限制。
我令S=1,T=n+1,从n到T建一条花费为0,流量为F+k的边。
上文中的?就相当于inf.
那么第二问的答案就是新建图的最大流的情况下的最小费用
代码<?)))><<
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<cmath> 8 #define ll long long 9 #define DB double 10 #define mod 1000000007 11 #define inf 147483600 12 using namespace std; 13 inline int read() 14 { 15 int x=0,w=1;char ch=getchar(); 16 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘) w=-1;ch=getchar();} 17 while(ch>=‘0‘ && ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar(); 18 return x*w; 19 } 20 const int N=1e6+10; 21 struct node{ 22 int u,v,c,fl,ne,w; 23 }e[N],b[N]; 24 int h[N],tot; 25 void add1(int u,int v,int c,int fl) 26 { 27 tot++;e[tot]=(node){u,v,c,fl,h[u],0};h[u]=tot; 28 } 29 void add(int u,int v,int c,int fl) 30 { 31 add1(u,v,c,fl);add1(v,u,-c,0); 32 } 33 deque<int>q; 34 int d[N],S,T,v[N]; 35 bool bfs() 36 { 37 for(int i=S;i<=T;++i)d[i]=inf,v[i]=0; 38 q.push_back(S);d[S]=0;v[S]=1; 39 while(!q.empty()) 40 { 41 int ff=q.front();q.pop_front();v[ff]=0; 42 for(int i=h[ff];i;i=e[i].ne) 43 { 44 int rr=e[i].v; 45 if(e[i].fl && d[rr]>d[ff]+e[i].c) 46 { 47 d[rr]=d[ff]+e[i].c; 48 if(!v[rr]) 49 { 50 v[rr]=1; 51 if(q.empty() || d[rr]>=d[q.front()]) q.push_back(rr); 52 else q.push_front(rr); 53 } 54 } 55 } 56 } 57 return d[T]!=inf; 58 } 59 int dfs(int u,int fl) 60 { 61 v[u]=1; 62 if(u==T || fl==0) return fl; 63 int get=0,f; 64 for(int i=h[u];i;i=e[i].ne) 65 { 66 int rr=e[i].v; 67 if(!v[rr] && e[i].fl && d[rr]==d[u]+e[i].c) 68 { 69 f=dfs(rr,min(fl,e[i].fl)); 70 if(f==0) continue; 71 get+=f;fl-=f; 72 e[i].fl-=f;e[i^1].fl+=f; 73 if(fl==0) break; 74 } 75 } 76 if(get==0) d[u]=inf; 77 return get; 78 } 79 int F,D; 80 int Flow() 81 { 82 F=0;D=0; 83 while(bfs()) 84 { 85 v[T]=1; 86 while(v[T]) 87 { 88 for(int i=S;i<=T;++i) v[i]=0; 89 int k=dfs(S,inf); 90 F+=k;D+=d[T]*k; 91 } 92 } 93 } 94 int n,m,K; 95 int main() 96 { 97 n=read();m=read();K=read(); 98 tot=1; 99 for(int i=1;i<=m;++i) 100 { 101 int x,y,z,w;x=read();y=read();z=read();w=read(); 102 add(x,y,1,z); 103 b[i]=(node){x,y,0,z,0,w}; 104 } 105 S=1;T=n; 106 Flow();printf("%d ",F);K+=F; 107 memset(h,0,sizeof(h));tot=1; 108 S=1;T=n+1; 109 for(int i=1;i<=m;++i) 110 { 111 int u,v,fl,w; 112 u=b[i].u;v=b[i].v;fl=b[i].fl;w=b[i].w; 113 add(u,v,0,fl);add(u,v,w,inf); 114 } 115 add(n,T,0,K); 116 Flow();printf("%d",D); 117 return 0; 118 }