洛谷 P3376 【【模板】网络最大流】
题目描述
如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。
输入
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)
输出
一行,包含一个正整数,即为该网络的最大流。
样例输入
4 5 4 3
4 2 30
4 3 20
2 3 20
2 1 30
1 3 40样例输出
50数据规模:
对于30%的数据:N<=10,M<=25
对于70%的数据:N<=200,M<=1000
对于100%的数据:N<=10000,M<=100000
网络流的模板题。汇总一些增广路算法。(Ford-Fulkerson, Edmond-Karp, Dinic, ISAP)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; struct edge {
int to,cap,rev;
}; const int maxn=, INF=0x7F7F7F7F;
int n,m;
vector <edge> G[maxn+]; edge make_edge(int to, int cap, int rev) {
edge x;
x.to=to, x.cap=cap, x.rev=rev;
return x;
} void add_edge(int from, int to, int cap) {
G[from].push_back(make_edge(to,cap,G[to].size()));
G[to].push_back(make_edge(from,,G[from].size()-));
} void init() {
for (int i=; i<=m; i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}
} namespace Ford_Fulkerson {
bool used[maxn+]; int dfs(int x, int t, int f) {
if (x==t) return f;
used[x]=true;
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (!used[e.to]&&e.cap>) {
int d=dfs(e.to,t,min(f,e.cap));
if (d>) {
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
} int max_flow(int s, int t) {
int flow=;
for(;;) {
memset(used,,sizeof(used));
int f=dfs(s,t,INF);
if (f==) return flow;
flow+=f;
}
}
} namespace Edmond_Karp {
bool vis[maxn+];
int prev[maxn+];
int pree[maxn+]; void bfs(int s) {
memset(vis,,sizeof(vis));
memset(prev,-,sizeof(prev));
memset(pree,-,sizeof(pree));
queue <int> q;
vis[s]=true;
q.push(s); while(!q.empty()) {
int x=q.front();
q.pop();
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&!vis[e.to]) {
prev[e.to]=x;
pree[e.to]=i;
vis[e.to]=true;
q.push(e.to);
}
}
}
} int max_flow(int s, int t) {
int flow=;
for(;;) {
bfs(s);
if (!vis[t]) return flow;
int d=INF;
for (int i=t; prev[i]!=-; i=prev[i])
d=min(d,G[prev[i]][pree[i]].cap);
for (int i=t; prev[i]!=-; i=prev[i]) {
edge &e=G[prev[i]][pree[i]];
e.cap-=d;
G[e.to][e.rev].cap+=d;
}
flow+=d;
}
}
} namespace Dinic {
int level[maxn+];
int iter[maxn+]; void bfs(int s) {
memset(level,-,sizeof(level));
queue <int> q;
level[s]=;
q.push(s); while (!q.empty()) {
int x=q.front();
q.pop();
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&level[e.to]<) {
level[e.to]=level[x]+;
q.push(e.to);
}
}
}
} int dfs(int x, int t, int f) {
if (x==t) return f;
for (int &i=iter[x]; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&level[e.to]>level[x]) {
int d=dfs(e.to,t,min(f,e.cap));
if (d>) {
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
} int max_flow(int s, int t) {
int flow=;
for(;;) {
bfs(s);
if (level[t]<) return flow;
memset(iter,,sizeof(iter));
int f;
while ((f=dfs(s,t,INF))>)
flow+=f;
}
}
} namespace ISAP {
int gap[maxn+];
int iter[maxn+];
int level[maxn+]; void bfs(int t) {
memset(gap,,sizeof(gap));
memset(level,-,sizeof(level));
queue <int> q;
level[t]=;
gap[level[t]]=;
q.push(t); while (!q.empty()) {
int x=q.front();
q.pop();
for (int i=; i<G[x].size(); i++) {
edge &e=G[x][i];
if (level[e.to]<) {
level[e.to]=level[x]+;
gap[level[e.to]]++;
q.push(e.to);
}
}
}
} int dfs(int x, int s, int t, int f) {
if (x==t) return f;
int flow=;
for (int &i=iter[x]; i<G[x].size(); i++) {
edge &e=G[x][i];
if (e.cap>&&level[x]==level[e.to]+) {
int d=dfs(e.to,s,t,min(f-flow,e.cap));
e.cap-=d;
G[e.to][e.rev].cap+=d;
flow+=d;
if (f==flow) return f;
}
} gap[level[x]]--;
if (gap[level[x]]==)
level[s]=n+;
iter[x]=;
gap[++level[x]]++;
return flow;
} int max_flow(int s, int t) {
int flow=;
bfs(t);
memset(iter,,sizeof(iter));
while (level[s]<=n)
flow+=dfs(s,s,t,INF);
return flow;
}
} int main() {
int s,t;
scanf("%d%d%d%d",&n,&m,&s,&t);
init();
printf("%d\n",ISAP::max_flow(s,t));
return ;
}
洛谷 P3376 【【模板】网络最大流】的更多相关文章
- 【最大流ISAP】洛谷P3376模板题
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- P3376 [模板] 网络最大流
https://www.luogu.org/blog/ONE-PIECE/wang-lao-liu-jiang-xie-zhi-dinic EK 292ms #include <bits/std ...
- 洛谷P3376【模板】网络最大流 ISAP
这篇博客写得非常好呀. 传送门 于是我是DCOI这一届第一个网络流写ISAP的人了,之后不用再被YKK她们嘲笑我用Dinic了!就是这样! 感觉ISAP是会比Dinic快,只分一次层,然后不能增广了再 ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
- 洛谷 P1546 最短网络 Agri-Net
题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...
- 洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)
洛谷P1546 最短网络 Agri-Net 最小生成树模板题. 直接使用 Kruskal 求解. 复杂度为 \(O(E\log E)\) . #include<stdio.h> #incl ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷 P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 洛谷——P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
随机推荐
- spring boot入门小案例
spring boot 入门小案例搭建 (1) 在Eclipse中新建一个maven project项目,目录结构如下所示: cn.com.rxyb中存放spring boot的启动类,applica ...
- C# 数组在内存中的存储
C# 数组是引用类型,那么在内存中是如何存储的呢? 在VS中调试C#程序,如何查看内存.寄存器.反汇编 在这篇文章里看到了如何在VS 中查看内存 先断点打在数组创建后语句那里,点debug->W ...
- [assembly: AssemblyVersion("1.0.1.*")] 指定版本字符串不符合所需格式 - major[.minor[.build[.revision]]]
报如下错误, 解决方法:打开项目文件,修改 打开项目文件修改:<Deterministic>true</Deterministic> 为:<Deterministic&g ...
- webstorm编辑器使用
1.自动生成vue文件模板,如图
- kaggle learn python
def has_lucky_number(nums): return any([num % 7 == 0 for num in nums]) def menu_is_boring(meals): &q ...
- Oarcle之用户管理 与 DCL
用户管理 1.创建一个账户 create user zhangsan identified by123456: 2.修改账户的密码 alter user zhangsan identified by ...
- 实验1 C语言开发环境使用和数据类型,运算符,表达式
part :验证性内容 .输出学号. #include<stdio.h> int main(void){ printf("); ; } .输入两个整数,求它们的乘积. #incl ...
- SpringBoot+Thymeleaf问题
springboot在controller返回数据到thymeleaf报404 用springboot做一个例子,访问controller可以返回数据,但是到thymeleaf却报404, 检查发现路 ...
- python函数部分----函数初识
0.来源http://www.cnblogs.com/jin-xin/articles/8241942.html 1.return 返回0个返回值,返回一个返回值.返回多个返回值 None.如果一个变 ...
- 修改Aptana Studio默认编码
1,修改:Text file encoding 2,修改:Initial HTML file contents