【题目大意】

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

【思路】

问题用Dinic搞一搞。问题二可以看出是费用流。

(1)残余网络中边还有一些容量,而如果利用这些容量,是不需要花费新的费用的。则将这些边的费用设置为0。

(2)对于原有的边,添加一条起点、终点相同的点,容量设置为INF,费用设置为一开始输入的扩容费用。再添加一个超级源点,和1之间添加一条边,容量为K,费用为0。

所谓的费用流,就是将EK中每一次搜索改为关于单位费用的SPFA即可,其余板块类似。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=+;
const int MAXM=+;
const int INF=0x7fffffff;
int n,m,k;//点数边数和需要扩充的容量
struct node
{
int to,cap,pos,w;
};
vector<node> E[MAXN];
int vis[MAXN];
int dis[MAXN];
int U[MAXM],V[MAXM],C[MAXM],W[MAXM];
int pre[MAXN],preedge[MAXN];//记录每次SPFA中每一个节点的前驱,以及当前节点在前驱的vector中是第几条边 void addedge(int u,int v,int c,int w)
{
E[u].push_back((node){v,c,E[v].size(),w});
E[v].push_back((node){u,,E[u].size()-,-w});/*失误把这里敲成了E[u],看了好久才看出来T T*/
} void init()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<m;i++)
{
scanf("%d%d%d%d",&U[i],&V[i],&C[i],&W[i]);
addedge(U[i],V[i],C[i],);
}
} int bfs()
{
queue<int> que;
memset(dis,-,sizeof(dis));
dis[]=;
que.push();
while (!que.empty())
{
int head=que.front();que.pop();
for (int i=;i<E[head].size();i++)
{
node tmp=E[head][i];
if (dis[tmp.to]==- && tmp.cap>)
{
dis[tmp.to]=dis[head]+;
que.push(tmp.to);
}
}
}
if (dis[n]==-) return ;
else return ;
} int dfs(int s,int e,int f)
{
vis[s]=;
if (s==e) return f;
for (int i=;i<E[s].size();i++)
{
node& tmp=E[s][i];
if (!vis[tmp.to] && tmp.cap> && dis[tmp.to]==dis[s]+)
{
int delta=dfs(tmp.to,e,min(f,tmp.cap));
if (delta>)
{
tmp.cap-=delta;
E[tmp.to][tmp.pos].cap+=delta;
return delta;
}
}
}
return ;
} void dinic()
{
int flow=;
while (bfs())
{
memset(vis,,sizeof(vis));
int f=dfs(,n,INF);
if (f==) break;
else flow+=f;
}
cout<<flow<<' ';
} void rebuild()
{
for (int i=;i<m;i++) addedge(U[i],V[i],INF,W[i]);
addedge(,,k,);
} int spfa(int u,int v)
{
memset(vis,,sizeof(vis));
for (int i=;i<=n;i++) dis[i]=INF;
memset(pre,-,sizeof(pre));
queue<int> que;
dis[]=;
vis[]=;
que.push();
while (!que.empty())
{
int head=que.front();
que.pop();
vis[head]=;
for (int i=;i<E[head].size();i++)
{
node& tmp=E[head][i];
if (tmp.cap> && dis[tmp.to]>dis[head]+tmp.w)
{
dis[tmp.to]=dis[head]+tmp.w;
pre[tmp.to]=head;
preedge[tmp.to]=i;
if (!vis[tmp.to])
{
vis[tmp.to]=;
que.push(tmp.to);
}
}
}
}
if (dis[n]==INF) return ;
else return ;
} void mcf()
{
int ans=;
while (spfa(,n))
{
int flow=INF;
for (int i=n;pre[i]!=-;i=pre[i])
flow=min(flow,E[pre[i]][preedge[i]].cap);
for (int i=n;pre[i]!=-;i=pre[i])
{
node& tmp=E[pre[i]][preedge[i]];
tmp.cap-=flow;
E[tmp.to][tmp.pos].cap+=flow;
ans+=flow*tmp.w;
}
}
cout<<ans<<endl;
} int main()
{
init();
dinic();
rebuild();
mcf();
return ;
}

【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容的更多相关文章

  1. BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3394  Solved: 1774 [Subm ...

  2. [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3330  Solved: 1739 [Subm ...

  3. 【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容

    引用题解: 最大流+费用流. 第一问最大流即可. 第二问为“最小费用最大流”. 由题意,这一问的可转化为在上一问的“残量网络”上,扩大一些边的容量,使能从新的图中的最大流为k. 那么易得:对于还有剩余 ...

  4. bzoj1834: [ZJOI2010]network 网络扩容 费用流

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

  5. 2018.10.13 bzoj1834: [ZJOI2010]network 网络扩容(最大流+费用流)

    传送门 网络流水题啊. 第一问直接放心跑最大流(本来还以为有什么tricktricktrick). 第二问就直接把原来的边(u,v,c,w)(u,v,c,w)(u,v,c,w)变成(u,v,c,0)( ...

  6. 【费用流】bzoj1834: [ZJOI2010]network 网络扩容

    还是稍微记一下这个拆点模型吧 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求:  1.在不扩容的情况下,1到N的最大流:  ...

  7. bzoj1834 [ZJOI2010]network 网络扩容

    第一问跑最大流,第二问新建一条边连接0和1,流量为上第一问的答案+k,费用为0,接下来图中每条边拆成两条边,第一条容量为C费用为0,第二条容量无穷费用为W,再跑一遍费用流即可. 代码 #include ...

  8. BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)

    挺直白的构图..最小费用最大流的定义. #include<cstdio> #include<cstring> #include<queue> #include< ...

  9. 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

    [BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...

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

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

随机推荐

  1. JAVA Frame 响应窗口关闭事件

    /* * To change this license header, choose License Headers in Project Properties. * To change this t ...

  2. HTML -- get与post提交方式的区别 -- (转)

    在写代码过程中,get与post是两种不同的提交方式.下面,列举出两种方式的不同. 方法/步骤   get是从服务器上获取数据,post是向服务器传送数据.   get是把参数数据队列加到提交表单的A ...

  3. 解决嵌套GridView显示不全的问题

    package com.adan.selectcitydome.view; import android.content.Context; import android.util.AttributeS ...

  4. Opencv模块功能介绍

    本文为原创作品,转载请注明出处 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/   站在巨 ...

  5. Bit banging

    Bit banging Bit banging is a technique for serial communications using software instead of dedicated ...

  6. linux dpm机制分析(上)【转】

    转自:http://blog.csdn.net/lixiaojie1012/article/details/23707681 1      DPM介绍 1.1        Dpm:  设备电源管理, ...

  7. [c++,bson] linux 使用 BSON 编程[www]

    [c++,bson] linux 使用 BSON 编程 http://blog.chinaunix.net/uid-28595538-id-4987410.html 1.js db=db.getSib ...

  8. C后端设计开发 - 第2章-内功-数据结构上卷

    正文 第2章-内功-数据结构上卷 后记 如果有错误, 欢迎指正. 有好的补充, 和疑问欢迎交流, 一块提高. 在此谢谢大家了.

  9. 破解 myeclipse 2014 professional,步骤很重要

    网易 博客 GACHA-动漫萌妹汇集地 LOFTER-最美图片社交 印像派-我的照片书 这些小语种最有前途,免费学 注册登录  加关注     日志     Windows下解决PostgreSQL8 ...

  10. Leetcode 之Add Binary(29)

    比较简单,细节:先将字符串翻转,注意进位. string addBinary(string a, string b) { string result; int len = a.size() > ...