洛谷 P2604 [ZJOI2010]网络扩容

来源:互联网 发布:中兴通讯讲师 知乎 编辑:程序博客网 时间:2024/06/05 20:54

题目描述

给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。

输入输出格式

输入格式:

输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

输出格式:

输出文件一行包含两个整数,分别表示问题1和问题2的答案。

输入输出样例

输入样例#1:
5 8 21 2 5 82 5 9 95 1 6 25 1 1 81 2 8 72 5 4 91 2 1 11 4 2 1
输出样例#1:
13 19

说明

30%的数据中,N<=100

100%的数据中,N<=1000,M<=5000,K<=10





第一问就是裸的最大流,第二问对于每一条边增加一条容量为inf,费用为w的边,增加源点和汇点,限制流量,求最小费用流。

#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int N=1005;const int M=5005;const int inf=1e9+7;int n,m,k,ans,cnt=1,s,t,hd[N],pre[N],w[M],dis[N];bool inq[N];queue<int>q;struct edge{int to,nxt,f,w;}v[4*M];void addedge(int x,int y,int z,int w){v[++cnt].to=y;v[cnt].f=z;v[cnt].w=w;v[cnt].nxt=hd[x];hd[x]=cnt;}bool bfs(){memset(pre,0,sizeof(pre));pre[s]=1;q.push(s);while(!q.empty()){int u=q.front();q.pop();for(int i=hd[u];i;i=v[i].nxt)if(v[i].f&&!pre[v[i].to]){pre[v[i].to]=pre[u]+1;q.push(v[i].to);}}return pre[t];}int dfs(int u,int lft){if(u==t||lft==0)return lft;int r=lft;for(int i=hd[u];i;i=v[i].nxt)if(r&&v[i].f&&pre[v[i].to]==pre[u]+1){int w=dfs(v[i].to,min(r,v[i].f));v[i].f-=w;v[i^1].f+=w;r-=w;if(!r)return lft;}if(lft==r)pre[u]=0;return lft-r;}bool spfa(){memset(dis,0x3f,sizeof(dis));memset(pre,0,sizeof(pre));dis[s]=0;q.push(s);inq[s]=1;while(!q.empty()){int u=q.front();q.pop();inq[u]=0;for(int i=hd[u];i;i=v[i].nxt)if(v[i].f&&dis[v[i].to]>dis[u]+v[i].w){dis[v[i].to]=dis[u]+v[i].w;pre[v[i].to]=i;if(!inq[v[i].to]){inq[v[i].to]=1;q.push(v[i].to);}}}return pre[t];}int mncst(){int res=0;while(spfa()){int flw=inf;for(int i=pre[t];i;i=pre[v[i^1].to])flw=min(flw,v[i].f);res+=dis[t]*flw;for(int i=pre[t];i;i=pre[v[i^1].to])v[i].f-=flw,v[i^1].f+=flw;}return res;}int mxflow(){int res=0;while(bfs())res+=dfs(s,inf);return res;}int main(){scanf("%d%d%d",&n,&m,&k);s=1,t=n;for(int i=1;i<=m;i++){int x,y,z;scanf("%d%d%d%d",&x,&y,&z,&w[i]);addedge(x,y,z,0),addedge(y,x,0,0);}printf("%d ",mxflow());for(int i=1;i<=m;i++)addedge(v[2*i+1].to,v[2*i].to,inf,w[i]),addedge(v[2*i].to,v[2*i+1].to,0,-w[i]);s=0,t=n+1;addedge(s,1,k,0),addedge(1,s,0,0),addedge(n,t,k,0),addedge(t,n,0,0);printf("%d\n",mncst());return 0;}


0 0
原创粉丝点击