【题目大意】

给定一张有向图,每条边都有一个容量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. VMware Workstation Pro 14 序列号

    VMware Workstation Pro 14 序列号: AA702-81D8N-0817Y-75PQT-Q70A4 YC592-8VF55-M81AZ-FWW5T-WVRV0 FC78K-FKE ...

  2. zuul进行rate limit

    maven <dependency> <groupId>com.marcosbarbero.cloud</groupId> <artifactId>sp ...

  3. 模型验证与模型集成(Ensemble)

    作者:吴晓军 原文:https://zhuanlan.zhihu.com/p/27424282 模型验证(Validation) 在Test Data的标签未知的情况下,我们需要自己构造测试数据来验证 ...

  4. import学习

    一.import  as     import socket, os, regex模块导入时可以使用 as 关键字来改变模块的引用对象名字: import os as system //当多个引入时  ...

  5. Linux命令--hostname和uname

    hostname命令 hostname命令用于显示和设置系统的主机名称.环境变量HOSTNAME也保存了当前的主机名.在使用hostname命令设置主机名后,系统并不会永久保存新的主机名,重新启动机器 ...

  6. 第三周main参数传递-1 课堂测试

    课堂测试 main参数传递-1 测试 参考 http://www.cnblogs.com/rocedu/p/6766748.html#SECCLA 在Linux下完成"求命令行传入整数参数的 ...

  7. 多表数据转化器MTDC

    需求 根据配置文件的映射规则,将一种模型和数据映射成另外一种模型和数据.如图: 其中,a1,b1,c1,d1为表主键,关系:A.a1=B.b1=C.c2=D.d1 解决思路 解析模型配置文件,将每个转 ...

  8. SUSE 11.3 linux ISO下载地址

    http://linux.iingen.unam.mx/pub/Linux/Suse/isos/SLES11/ SLE-11-SP3-SDK-DVD-i586-GM-DVD1.iso 6deaa960 ...

  9. 己动手创建最精简的Linux

    己动手创建最精简的Linux http://blog.sina.com.cn/s/blog_71c87c170101e7ru.html 首次 LFS 搭建全过程 http://zmyxn.blog.5 ...

  10. mongodb-linux-x86_64

    卷 DataDisk 的文件夹 PATH 列表卷序列号为 4A8E-D95CD:.│  1.txt│  GNU-AGPL-3.0│  MPL-2│  README│  THIRD-PARTY-NOTI ...