洛谷 P2604 [ZJOI2010]网络扩容
题目描述
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。
输入输出格式
输入格式:
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
输出格式:
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
输入输出样例
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
13 19
说明
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
第一问 任何费用为0,流量为给定流量的最大流
第二问 源点到第一个点流量为k 其他流量为inf ,费用为给定费用的费用流
#include <cstring>
#include <ctype.h>
#include <cstdio>
#include <queue>
#define M 50005
#define inf 0x7fffffff using namespace std;
void read(int &x)
{
x=;bool f=;
register char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
x=f?(~x)+:x;
}
struct Edge
{
int next,to,flow,value;
Edge(int next=,int to=,int flow=,int value=) :next(next),to(to),flow(flow),value(value) {}
}edge[M<<];
bool vis[M<<];
int u[M],v[M],c[M],w[M],n,m,k,dep[M<<],dis[M<<],fa[M<<],flow[M<<],head[M<<],cnt=;
void insert(int u,int v,int w,int l)
{
edge[++cnt]=Edge(head[u],v,w,l);
head[u]=cnt;
}
bool bfs(int s,int t)
{
memset(dep,-,sizeof(dep));
dep[s]=;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int now=Q.front();
Q.pop();
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
if(dep[v]==-&&edge[i].flow>)
{
dep[v]=dep[now]+;
if(v==t) return true;
Q.push(v);
}
}
}
return false;
}
int min(int a,int b) {return a>b?b:a;}
int dfs(int now,int t,int came_flow)
{
if(now==t||came_flow==) return came_flow;
int f,res=;
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
if(dep[v]==dep[now]+&&edge[i].flow>&&(f=dfs(v,t,min(came_flow,edge[i].flow))))
{
res+=f;
came_flow-=f;
edge[i].flow-=f;
edge[i^].flow+=f;
if(came_flow==) break;
}
}
if(res!=came_flow) dep[now]=-;
return res;
}
bool spfa(int s,int t)
{
for(int i=s;i<=t;i++) {flow[i]=inf;dis[i]=inf;vis[i]=;}
vis[s]=;
fa[s]=;
dis[s]=;
queue<int>Q;
Q.push(s);
while(!Q.empty())
{
int now=Q.front();
Q.pop();
vis[now]=;
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[now]+edge[i].value&&edge[i].flow>)
{
dis[v]=dis[now]+edge[i].value;
flow[v]=min(flow[now],edge[i].flow);
fa[v]=i;
if(!vis[v])
{
vis[v]=;
Q.push(v);
}
}
}
}
return dis[t]<inf;
}
int update(int s,int t)
{
int x=flow[t];
for(int i=t;i!=s&&i;i=edge[fa[i]^].to)
{
edge[fa[i]].flow-=x;
edge[fa[i]^].flow+=x;
}
return dis[t]*x;
}
int dinic(int s,int t,int type)
{
int ans=;
if(type==)
for(;bfs(s,t);ans+=dfs(s,t,inf));
else for(;spfa(s,t);ans+=update(s,t));
return ans;
}
int main()
{
read(n);
read(m);
read(k);
for(int i=;i<=m;i++)
{
read(u[i]);
read(v[i]);
read(c[i]);
read(w[i]);
insert(u[i],v[i],c[i],);
insert(v[i],u[i],,);
}
printf("%d ",dinic(,n,));
for(int i=;i<=m;i++)
{
insert(u[i],v[i],inf,w[i]);
insert(v[i],u[i],,-w[i]);
}
insert(,,k,);
insert(,,,);
printf("%d\n",dinic(,n,));
return ;
}
洛谷 P2604 [ZJOI2010]网络扩容的更多相关文章
- 洛谷 P2604 [ZJOI2010]网络扩容 解题报告
P2604 [ZJOI2010]网络扩容 题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. ...
- 洛谷$P2604\ [ZJOI2010]$网络扩容 网络流
正解:网络流 解题报告: 传送门$QwQ$ 昂第一问跑个最大流就成不说$QwQ$ 然后第二问,首先原来剩下的边就成了费用为0的边?然后原来的所有边连接的两点都给加上流量为$inf$费用为$w$的边,保 ...
- [洛谷P2604][ZJOI2010]网络扩容
题目大意:给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小费用. 题解 ...
- 【题解】Luogu P2604 [ZJOI2010]网络扩容
原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...
- BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
题目连接: (luogu) https://www.luogu.org/problemnew/show/P2604 (bzoj) https://www.lydsy.com/JudgeOnline/p ...
- P2604 [ZJOI2010]网络扩容
思路 简单的费用流问题,跑出第一问后在残量网络上加边求最小费用即可 代码 #include <cstdio> #include <algorithm> #include < ...
- 洛谷 P1546 最短网络 Agri-Net
题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...
- [Luogu 2604] ZJOI2010 网络扩容
[Luogu 2604] ZJOI2010 网络扩容 第一问直接最大流. 第二问,添加一遍带费用的边,边权 INF,超级源点连源点一条容量为 \(k\) 的边来限流,跑费用流. 大约是第一次用 nam ...
- 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)
洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...
随机推荐
- BZOJ1453: [WC2005]Dface双面棋盘
离线LCT维护MST,和3082的方法一样.然而比较码农,适合颓废的时候写. PS:线段树分治要好写得多,LCT比较自娱自乐. #include<bits/stdc++.h> using ...
- javascript之常遇到的浏览器兼容问题和解决方法
转自http://www.cnblogs.com/duenyang/p/6066737.html 常遇到的关于浏览器的宽高问题: var winW=document.body.clientWidth| ...
- 【转】Chrome headless 模式
原文地址: http://www.cnblogs.com/fnng/p/7797839.html 我们在通过Selenium运行自动化测试时,必须要启动浏览器,浏览器的启动与关闭必然会影响执行效率,而 ...
- backface-visibility
浏览器支持 只有 Internet Explorer 10+ 和 Firefox 支持 backface-visibility 属性. Opera 15+.Safari 和 Chrome 支持替代的 ...
- mysql连接过多-报错
有两种方法: 1,错误连接参数 max_connect_errors,在配置文件中调整增大. 比如:修改mysql配置文件,在[mysqld]字段下面添加 max_connect_errors=102 ...
- JAVA基础--面向对象08
一.final关键字 有的时候不想别人重写我的方法,使用final关键字修饰该方法,final:最后的,最终的,可以修饰类.修饰函数.修饰变量,修饰类:该类不能被继承:直接写在class关键字前面 修 ...
- Android Studio提示忽略大小写
Android Studio的自动提示功能非常之强大,但是,如果你要输入“String”,你输入“string”,这个是不会提示的,也就是大小写敏感的,不爽是吗? 选择大小写不敏感就ok了!这样你想怎 ...
- 51nod 1051 最大子矩阵和(DP)
题意 略 分析 一道经典的DP题,但是我弱到差点做不出来,真的垃圾 设置\(sum(i,j)代表1-i行第j列的前缀和\),然后枚举行i和行j,再枚举列k,做一遍类似一维的最大子段和即可 #inclu ...
- UVALive 6833【模拟】
题意: 算从左往右的值,先乘后加的值,数的范围<=9= =,然后根据满足的条件输出字符. 思路: 从左往右就是直接来了,先做乘法就是乘法两边的数字靠向右边那个,且左边那个为0,然后所有值一加就好 ...
- python __builtins__ frozenset类 (27)
27.'frozenset', 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素. class frozenset(object) | frozenset() -> empty froze ...