分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

BZOJ 1834 ZJOI2010 network 网络扩容

发布时间:2023-09-06 01:53责任编辑:林大明关键词:暂无标签

1834: [ZJOI2010]network 网络扩容

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 3735  Solved: 2001
[Submit][Status][Discuss]

Description

给定一张有向图,每条边都有一个容量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的答案。

Sample Input

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

Sample Output

13 19

HINT

 

Source

大水提,第一问就是最大流,dinic跑一下

第二问,我们在残量网络上进行建图,在题目给的那些边都进行连边,流量inf,费用为题目给的费用

dinic跑完的剩下边不用动,费用为0即可,s向1连一条流量为k,费用为0的边  跑一下最小费用最大流即可

#include <bits/stdc++.h>#define ll long long#define inf 1e9+10using namespace std;inline int read(){int x=0;int f=1;char ch=getchar();while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();}return x*f;}const int MAXN=1e5+10;struct node{int y,next,back,flow,w;}e[MAXN];int len,linkk[MAXN],head,tail,level[1100],s,t,n,m,x[MAXN],y[MAXN],f[MAXN],c[MAXN],dis[1100],ans,vis[1100],q[MAXN],k;inline void insert(int x,int y,int f,int c){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].flow=f;e[len].back=len+1;e[len].w=c;e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].flow=0;e[len].back=len-1;e[len].w=-c;}namespace dinicc{inline bool getlevel(){head=tail=0;memset(level,-1,sizeof(level));level[s]=0;q[++tail]=s;while(head<tail){int tn=q[++head];for(int i=linkk[tn];i;i=e[i].next){if(level[e[i].y]==-1&&e[i].flow){level[e[i].y]=level[tn]+1;q[++tail]=e[i].y;}}}return level[t]>=0;}inline int getmaxflow(int x,int flow){if(x==t) return flow;int f=0,d;for(int i=linkk[x];i;i=e[i].next){if(e[i].flow&&level[e[i].y]==level[x]+1){if(d=getmaxflow(e[i].y,min(e[i].flow,flow-f))){f+=d;e[i].flow-=d;e[e[i].back].flow+=d;if(f==flow) return f;}}}if(!f) level[x]=-1;return f;}inline int dinic(){int ans=0,d;while(getlevel()){while(d=getmaxflow(s,inf)) ans+=d;}return ans;}}namespace zkww{inline bool getdis(){memset(vis,0,sizeof(vis));memset(dis,10,sizeof(dis));dis[t]=0;deque<int>q;q.push_back(t);while(!q.empty()){int tn=q.front();q.pop_front();for(int i=linkk[tn];i;i=e[i].next){if(dis[tn]-e[i].w<dis[e[i].y]&&e[e[i].back].flow){dis[e[i].y]=dis[tn]-e[i].w;if(!vis[e[i].y]){vis[e[i].y]=1;if(!q.empty()&&dis[e[i].y]<dis[q.front()]) q.push_front(e[i].y);else q.push_back(e[i].y);}}}vis[tn]=0;}return dis[s]<168430090;}inline int getcost(int x,int flow){ ???????int f=0,d;vis[x]=1;if(x==t) return flow;for(int i=linkk[x];i;i=e[i].next){if(e[i].flow&&dis[e[i].y]==dis[x]-e[i].w&&!vis[e[i].y]){if(d=getcost(e[i].y,min(flow-f,e[i].flow))){f+=d;e[i].flow-=d;e[e[i].back].flow+=d;ans+=e[i].w*d;if(f==flow) return f;}}}return f;}inline void zkw(){while(getdis()){vis[t]=1;while(vis[t]){memset(vis,0,sizeof(vis));getcost(s,inf);}}}}void build(){s=0;t=n;insert(s,1,k,0);for(int i=1;i<=m;i++){insert(x[i],y[i],inf,c[i]);}}int main(){using namespace dinicc;using namespace zkww;n=read();m=read();k=read();s=1;t=n;for(int i=1;i<=m;i++){x[i]=read();y[i]=read();f[i]=read();c[i]=read();insert(x[i],y[i],f[i],0);}ans=dinic();cout<<ans<<‘ ‘;build();ans=0;zkw();cout<<ans<<endl;return 0;}

  

BZOJ 1834 ZJOI2010 network 网络扩容

原文地址:https://www.cnblogs.com/something-for-nothing/p/9012332.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved