bzoj 1834 [ZJOI2010] network 网络扩容(费用流)
2018-08-21 14:32
393 查看
题目描述
给定一张有向图,每条边都有一个容量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 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
输出样例#1: 复制
13 19
说明
30%的数据中,N<=100100%的数据中,N<=1000,M<=5000,K<=10
[b]题解[/b]
话说其实不用新建图的……我看到好几位大佬的做法都是0.5倍经验+码量巨大的……
实际上只要直接跑一个费用流就行了。对于第一问,我们直接连边,然后令费用为$0$,跑一遍,输出最大流即可
对于第二问,只要在原来的每条边上再连一条边,容$inf$费为扩边费用,然后$k$的限制只要再建一个源点往$1$连容$k$费$0$的边。在残量网络上再跑一遍,输出最小费用即可
考虑为什么这样做是对的。因为要跑最小费用最大流,而原图是无花费的最大流,那么只要在此残量网络上继续增广,就可以保证跑出最小费用了
//minamoto #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define inf 0x3f3f3f3f using namespace std; #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) char buf[1<<21],*p1=buf,*p2=buf; inline int read(){ #define num ch-'0' char ch;bool flag=0;int res; while(!isdigit(ch=getc())) (ch=='-')&&(flag=true); for(res=num;isdigit(ch=getc());res=res*10+num); (flag)&&(res=-res); #undef num return res; } const int N=1005,M=50005; struct node{ int u,v,f,e; node(){} node(int u,int v,int f,int e):u(u),v(v),f(f),e(e){} }E[M]; int ver[M],Next[M],head ,edge[M],flow[M],tot=1; int dis ,disf ,vis ,Pre ,last ; int n,m,k,s,t,maxflow,mincost; queue<int> q; inline void add(int u,int v,int f,int e){ ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e; ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=0,edge[tot]=-e; } bool spfa(){ memset(dis,0x3f,sizeof(dis)); q.push(s),dis[s]=0,disf[s]=inf,Pre[t]=-1; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i;i=Next[i]){ int v=ver[i]; if(flow[i]&&dis[v]>dis[u]+edge[i]){ dis[v]=dis[u]+edge[i],Pre[v]=u,last[v]=i; disf[v]=min(disf[u],flow[i]); if(!vis[v]) vis[v]=1,q.push(v); } } } return ~Pre[t]; } void dinic(){ while(spfa()){ int u=t;maxflow+=disf[t],mincost+=disf[t]*dis[t]; while(u!=s){ flow[last[u]]-=disf[t]; flow[last[u]^1]+=disf[t]; u=Pre[u]; } } } int main(){ n=read(),m=read(),k=read(); s=1,t=n; for(int i=1;i<=m;++i){ int u=read(),v=read(),f=read(),e=read(); E[i]=node(u,v,f,e); add(u,v,f,0); } dinic(); printf("%d ",maxflow); for(int i=1;i<=m;++i){ int u=E[i].u,v=E[i].v,e=E[i].e; add(u,v,inf,e); } s=0; add(s,1,k,0); dinic(); printf("%d\n",mincost); return 0; }
相关文章推荐
- bzoj1834 [ZJOI2010]network 网络扩容(费用流)
- [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流
- 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容
- bzoj 1834: [ZJOI2010]network 网络扩容 网络流+费用流
- BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】
- BZOJ_1834_[ZJOI2010]network 网络扩容_费用流
- BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)
- 【bzoj1834】[ZJOI2010]network 网络扩容 费用流
- bzoj1834 [ZJOI2010]network 网络扩容 最大流+费用流
- BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)
- 【bzoj1834】[ZJOI2010]network 网络扩容
- [bzoj1834][ZJOI2010]network 网络扩容
- [bzoj1834][ZJOI2010]network 网络扩容
- [BZOJ1834][ZJOI2010]网络扩容(费用流)
- BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
- [BZOJ1834][ZJOI2010]network 网络扩容
- [BZOJ1834][ZJOI2010]network 网络扩容
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- 【bzoj1834】[ZJOI2010]network 网络扩容 最大流+最小费用流
- bzoj1834[ZJOI2010]network 网络扩容【最大流+费用流】