题目描述

给定一张有向图,每条边都有一个容量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. codevs1258关路灯

    传送门 1258 关路灯  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master   题目描述 Description 多瑞卡得到了一份有趣而高薪的工作.每天早晨他 ...

  2. Java多线程:线程状态以及wait(), notify(), notifyAll()

    一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运 ...

  3. 批处理(cmd)的学习记录

    批处理的使基本使用 Command Introduction Example set 设置环境变量 set name="小明" call 启动应用程序   rem 解释说明,可通过 ...

  4. Codeforces626C 【二分】

    题意: 有两种搬砖的(不好好打代码就只能搬砖了),有n个sou弱的只能搬2块,m个stronger一点的能搬3块,他们想作死的独自把砖垒高,然后每个人垒的高度还各不相同,问你存在的最高高度的最小: 思 ...

  5. 洛谷P1850 换教室(概率dp)

    传送门 我的floyd竟然写错了?今年NOIP怕不是要爆零了? 这就是一个概率dp 我们用$dp[i][j][k]$表示在第$i$个时间段,已经申请了$j$次,$k$表示本次换或不换,然后直接暴力转移 ...

  6. EasyUI创建选项卡并判断是否打开

    //创建选项卡:判断选项卡是否打开,如果以打开则定位到选项卡,否则创建 function addPanel(title) { var bol = $('#main_tabs').tabs('exist ...

  7. P1228-重叠的图像

    一道很水的topsort,唉?怎么交了14遍...(某人用我的代码刚好卡过,我怎么过不去...[鄙视][鄙视][鄙视]) #include <bits/stdc++.h> using na ...

  8. Docker镜像文件操作

    1什么是Docker镜像 Docker镜像是由文件系统叠加而成(是一种文件的存储形式).最底端是一个文件引导系统,即bootfs,这很像典型的Linux/Unix的引导文件系统.Docker用户几乎永 ...

  9. eclipse中alt+/的作用

    一般情况下alt+/有代码提示作用,还有代码提示的快捷代码也不是alt+/,因此要恢复代码提示用alt+/.需要做两件事.在 Window - Preferences - General - Keys ...

  10. C# ref和out传递参数总结

    如有雷同,不胜荣幸,若转载,请注明 C#中ref和out传递参数总结,两个都可用来传递参数,ref使用时必须先进行初始化,out则不需要,只要在返回之前赋值即可,文字废话到此,下面直接上例子 ref例 ...