题目描述

给定一张有向图,每条边都有一个容量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<=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]网络扩容的更多相关文章

  1. 洛谷 P2604 [ZJOI2010]网络扩容 解题报告

    P2604 [ZJOI2010]网络扩容 题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. ...

  2. 洛谷$P2604\ [ZJOI2010]$网络扩容 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 昂第一问跑个最大流就成不说$QwQ$ 然后第二问,首先原来剩下的边就成了费用为0的边?然后原来的所有边连接的两点都给加上流量为$inf$费用为$w$的边,保 ...

  3. [洛谷P2604][ZJOI2010]网络扩容

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

  4. 【题解】Luogu P2604 [ZJOI2010]网络扩容

    原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...

  5. BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)

    题目连接: (luogu) https://www.luogu.org/problemnew/show/P2604 (bzoj) https://www.lydsy.com/JudgeOnline/p ...

  6. P2604 [ZJOI2010]网络扩容

    思路 简单的费用流问题,跑出第一问后在残量网络上加边求最小费用即可 代码 #include <cstdio> #include <algorithm> #include < ...

  7. 洛谷 P1546 最短网络 Agri-Net

    题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...

  8. [Luogu 2604] ZJOI2010 网络扩容

    [Luogu 2604] ZJOI2010 网络扩容 第一问直接最大流. 第二问,添加一遍带费用的边,边权 INF,超级源点连源点一条容量为 \(k\) 的边来限流,跑费用流. 大约是第一次用 nam ...

  9. 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)

    洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...

随机推荐

  1. POJ-3352 Redundant Paths

    In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) t ...

  2. python split space

    发现自己写python的空格split还挺多坎的,尤其是最后一个是空格的情形: def split(s): i = 0 ans = [] while i < len(s): start = i ...

  3. BZOJ_1264_[AHOI2006]基因匹配Match_树状数组

    BZOJ_1264_[AHOI2006]基因匹配Match_树状数组 Description 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种 ...

  4. Spring AOP schema找不到报错 原

    转自:https://my.oschina.net/zetaplusae/blog/144821 使用jersey+spring构建RESTful服务,并将应用部署在不能连接外网的服务器上.部署时,报 ...

  5. CSS中style用法详解

    转自:http://www.cnblogs.com/xingxingchongchong/p/6501575.html css样式表按其所在位置分三种: 1.内嵌样式表 2.内部样式表 3.外部样式表 ...

  6. 自定义HTML中select控件

    HTML中默认的select控件比较难看,大家可以参考,本文提供一种解决思路,当然也可以用CSS实现. function selectInit(tid,isIn){ if(!$("#&quo ...

  7. emacs版本差异(转载)

    emacs23 就是原装的,由 gnu 发布的 emacs.emacs-lucid 是由 ubuntu 调整过的.emacs-nox 是不带 x system 的 emacs 版本.除非只在终端下用, ...

  8. lightoj 1125【01背包变性】

    题意: 从n个数里选出m个来,还要使得这m个数之和被d整除. 给一个n和q,再给n个数,再给q个询问,每个询问包含两个数,d,m; 对于每个case输出每个q个询问的可行的方案数. 思路: 每个数只能 ...

  9. Tasks 多核查找最大最小值问题

    先贴下代码 _Datas.ParallelForEach(arg_nDataStartIndex, arg_nDataCount, (data) => { dMax = dMax.Max(dat ...

  10. python __builtins__ frozenset类 (27)

    27.'frozenset', 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素. class frozenset(object) | frozenset() -> empty froze ...