对于第一问,跑一遍最大流即可.

对于第二问,在残量网络上的两点间建立边 <u,v>,容量为无限大,费用为扩充费用.

跑一遍最小费用流即可.

Code:

#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin)
#define inf 100000000
#define maxn 100000
#define ll long long
using namespace std;
struct Edges{
int u,v,c,w;
}EDGE[maxn];
int n,m,k,s,t;
struct Edge{
int from,to,cap,cost;
Edge(int u,int v,int c,int f) : from(u),to(v),cap(c),cost(f){}
};
vector<int>G[maxn];
vector<Edge>edges;
void addedge(int u,int v,int c,int f){
edges.push_back(Edge(u,v,c,f));
edges.push_back(Edge(v,u,0,-f));
int o = edges.size();
G[u].push_back(o - 2);
G[v].push_back(o - 1);
}
namespace Dinic{
int d[maxn],vis[maxn];
queue<int>Q;
int BFS(){
memset(vis,0,sizeof(vis));
vis[s] = 1,d[s] = 0; Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
int sz = G[u].size();
for(int i=0;i<sz;++i) {
Edge r = edges[G[u][i]];
if(!vis[r.to] && r.cap > 0) {
d[r.to] = d[u] + 1;
vis[r.to] = 1;
Q.push(r.to);
}
}
}
return vis[t];
}
int current[maxn];
int DFS(int x,int cur){
if(x==t) return cur;
int flow=0,f;
int sz = G[x].size();
for(int i=current[x];i<sz;++i) {
int u = G[x][i];
Edge r = edges[u];
if(d[r.to] == d[x] + 1 && r.cap > 0){
f = DFS(r.to,min(cur,r.cap));
if(f > 0) {
flow += f;
cur -= f;
edges[u].cap -= f;
edges[u^1].cap += f;
}
}
if(cur==0) break;
}
return flow;
}
int maxflow(){
int flow=0;
while(BFS()){
memset(current,0,sizeof(current));
flow += DFS(s,inf);
}
return flow;
}
};
namespace MCMF{
queue<int>Q;
int d[maxn],inq[maxn];
int flow2[maxn],a[maxn];
long long ans;
int SPFA(){
for(int i=0;i<maxn;++i) d[i] = flow2[i] = inf;
memset(inq,0,sizeof(inq));
inq[s] = 1; d[s] = 0;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop(); inq[u] = 0;
int sz = G[u].size();
for(int i=0;i<sz;++i) {
Edge r = edges[G[u][i]];
if(r.cap > 0 && d[r.to] > d[u] + r.cost) {
d[r.to] = d[u] + r.cost;
a[r.to] = G[u][i];
flow2[r.to] = min(flow2[u],r.cap);
if(!inq[r.to]) {
inq[r.to] = 1;
Q.push(r.to);
}
}
}
}
if(flow2[t] == inf) return 0;
int f = flow2[t];
edges[a[t]].cap -= f, edges[a[t] ^ 1].cap += f;
int u = edges[a[t]].from;
while(u != s){
edges[a[u]].cap -= f;
edges[a[u]^1].cap += f;
u = edges[a[u]].from;
}
ans += (ll)(d[t] * f);
return 1;
}
long long getcost(){
while(SPFA());
return ans;
}
};
int main(){
//setIO("input");
scanf("%d%d%d",&n,&m,&k);
s = 1, t = n;
for(int i = 1;i <= m; ++i) scanf("%d%d%d%d",&EDGE[i].u,&EDGE[i].v,&EDGE[i].c,&EDGE[i].w);
for(int i = 1;i <= m; ++i)
addedge(EDGE[i].u,EDGE[i].v,EDGE[i].c,0);
printf("%d ",Dinic::maxflow());
for(int i = 1;i <= m; ++i)
addedge(EDGE[i].u,EDGE[i].v,inf,EDGE[i].w);
s = 0 , t = n + 1;
addedge(s,1,k,0);
addedge(n,n+1,k,0);
printf("%lld",MCMF::getcost());
return 0;
}

  

BZOJ 1834: [ZJOI2010]network 网络扩容 最小费用流_最大流_残量网络的更多相关文章

  1. BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)

    第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然  后跑最小费用最大流就OK了. ---- ...

  2. bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一 ...

  3. bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题意] 给定一个有向图,每条边有容量C,扩容费用W,问最大流和使容量增加K的最 ...

  4. bzoj 1834: [ZJOI2010]network 网络扩容【最大流+最小费用最大流】

    第一问直接跑最大流即可.建图的时候按照费用流建,费用为0. 对于第二问,在第一问dinic剩下的残量网络上建图,对原图的每条边(i,j),建(i,j,inf,cij),表示可以用c的花费增广这条路.然 ...

  5. 最小割最大流定理&残量网络的性质

    最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...

  6. BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题目大意] 给定一张有向图,每条边都有一个容量C和一个扩容费用W. 这里扩容费 ...

  7. bzoj 1834: [ZJOI2010]network 网络扩容

    #include<cstdio> #include<iostream> #include<cstring> #define M 100000 #define inf ...

  8. BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)

    一看就知道是模板题= = ,不说什么了= = PS:回去搞期末了,暑假再来刷题了 CODE: #include<cstdio> #include<iostream> #incl ...

  9. BZOJ 1834 ZJOI2010 network 网络扩展 Dinic+EK费用流

    标题效果:给定一个n积分m无向图边,每一方有一个扩展的成本c.代表扩张1费用的交通,寻求最大流量和扩大的最大流量k最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正 ...

随机推荐

  1. Javase 简单代码练习

    public class Test10 { public static void main(String[] args) { System.out.println("------------ ...

  2. Linux下挂载分区 (本人实例)

    设置分区开机自动挂载 要在/etc/fstab里设置一行 把上面空格去掉就行了

  3. python数据分析------文本挖掘(jieba)

    1.import jieba jieba的cut函数有三个模式:全模式.精准模式.搜索引擎模式 1 精确模式,试图将句子最精确地切开,适合文本分析: 2 全模式,把句子中所有的可以成词的词语都扫描出来 ...

  4. 第一章 JavaScript 简介

    1.1   JavaScript 的简史 JavaScript 诞生于1995年 ,后由 欧洲计算机制造商协会( ECMA,European Computer Manufacturers Associ ...

  5. node中exports和module.exports的关系及使用

    在node中,需要记住,在使用exports和module.exports的时候,实际输出的是module.exports. exports指向module.exports,是module.expor ...

  6. linux chattr用法

    在linux中,我们有的时候发现linux无法删除一个文件或者目录. huskiesir第一次遇见这个问题还是在一次服务器被不法分子入侵之后的事情,我就发现某个进程很多,根据进程的名字,我搜索关键字找 ...

  7. struct 模块解决 TCP黏包问题

    首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket ​ sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...

  8. 【hihocoder 1312】搜索三·启发式搜索(启发式搜索写法)

    [题目链接]:http://hihocoder.com/problemset/problem/1312?sid=1092363 [题意] [题解] 定义一个A*函数 f = step+val 这里的v ...

  9. 因一段JavaScript代码引发的闲扯

    前两天,一朋友给我发了一段JavaScript代码: function f1(){ var n=999; nAdd=function(){ n+=1 }; function f2(){ alert(n ...

  10. CCDirector导演类

    CCDirector类是Cocos2D-x游戏引擎的核心.它用来创建而且控制着屏幕的显示,同一时候控制场景的显示时间和显示方式. 在整个游戏里一般仅仅有一个导演.游戏的開始.结束.暂停都会调用CCDi ...