【模板】网络最大流(EK、Dinic、ISAP)(网络流)/洛谷P3376
题目链接
https://www.luogu.com.cn/problem/P3376
题目大意
输入格式
第一行包含四个正整数 \(n,m,s,t\),分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来\(m\)行,每行包含三个正整数 \(u_i,v_i,w_i\),表示第 \(i\) 条有向边从 \(u_i\) 出发,到达 \(v_i\),边权为 \(w_i\)(即该边最大流量为 \(w_i\) )。
输出格式
一行,包含一个正整数,即为该网络的最大流。
题目解析
(待补充,咕咕咕。。。)
参考代码
\(EK\)
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const long long INF = (1LL << 32);
struct Edge{
int from, to;
long long cap, flow;
};
int n, m, s, t;
long long a[N];
int p[N];
vector <Edge> e;
vector <int> G[N];
void addEdge(int from, int to, int cap, int i)
{
e.push_back((Edge){from, to, cap, 0});
e.push_back((Edge){to, from, 0, 0});
G[from].push_back(i << 1);
G[to].push_back((i << 1)+1);
}
long long maxflow()
{
long long flow = 0;
while (1)
{
memset(a, 0, sizeof(a));
a[s] = INF;
queue <int> q;
q.push(s);
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i=0; i<G[x].size(); ++i)
{
Edge &b = e[G[x][i]];
if (!a[b.to] && b.cap > b.flow)
{
p[b.to] = G[x][i];
a[b.to] = min(a[x], b.cap-b.flow);
q.push(b.to);
}
}
if (a[t]) break;
}
if (!a[t]) break;
for (int u=t; u!=s; u=e[p[u]].from)
{
e[p[u]].flow += a[t];
e[p[u]^1].flow -= a[t];
}
flow += a[t];
}
return flow;
}
int main()
{
int u, v, w;
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i=0; i<m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w, i);
}
printf("%lld\n", maxflow());
return 0;
}
\(Dinic\)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int INF = 2147483647;
const int N = 205;
struct Edge{
int from, to, cap, flow;
};
int cur[N], depth[N];
int n, m, s, t;
vector <Edge> e;
vector <int> G[N];
void addEdge(int u, int v, int w, int i)
{
e.push_back((Edge){u, v, w, 0});
e.push_back((Edge){v, u, 0, 0});
G[u].push_back(i);
G[v].push_back(i^1);
}
int BFS()
{
queue <int> Q;
memset(depth, 0, sizeof depth);
depth[s] = 1;
Q.push(s);
while (!Q.empty())
{
int u = Q.front(); Q.pop();
for (int i = 0; i < G[u].size(); ++i) {
Edge& b = e[G[u][i]];
if (!depth[b.to] && b.cap > b.flow)
{
depth[b.to] = depth[u] + 1;
Q.push(b.to);
}
}
}
return depth[t];
}
int DFS(int x, int a)
{
if (x == t || !a) return a;
int flow = 0;
for (int& i = cur[x]; i < G[x].size(); ++i) {
Edge& b = e[G[x][i]];
if (depth[b.to] == depth[x]+1 && b.cap > b.flow)
{
if (int c = DFS(b.to, min(a, b.cap - b.flow)))
{
b.flow += c;
e[G[x][i]^1].flow -= c;
flow += c;
a -= c;
if (!a) break;
}
}
}
return flow;
}
ll maxFlow_Dinic()
{
ll ans = 0;
while (BFS()) {
memset(cur, 0, sizeof cur);
ans += DFS(s, INF);
}
return ans;
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 0; i < m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w, i << 1);
}
printf("%lld\n", maxFlow_Dinic());
return 0;
}
\(ISAP\)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 205;
const int INF = 2147483647;
struct Edge {
int from, to, cap, flow;
};
int n, m, s, t, cnt, gap[N], cur[N], dep[N];
vector <int> G[N];
vector <Edge> e;
void addEdge(int u, int v, int w, int i)
{
e.push_back((Edge){u, v, w, 0});
e.push_back((Edge){v, u, 0, 0});
G[u].push_back(i);
G[v].push_back(i^1);
}
void init()
{
memset(gap, 0, sizeof gap);
memset(cur, 0, sizeof cur);
memset(dep, 0, sizeof dep);
++gap[dep[t] = 1];
queue <int> Q;
Q.push(t);
while (!Q.empty()) {
int x=Q.front(); Q.pop();
for (int i = 0; i < G[x].size(); i++)
{
int v = e[G[x][i]].to;
if (!dep[v])
{
++gap[dep[v] = dep[x]+1];
Q.push(v);
}
}
}
}
int augment(int x, int a)
{
if (x == t || !a) return a;
int flow = 0;
for (int &i=cur[x]; i < G[x].size(); i++)
{
Edge& b = e[G[x][i]];
if (dep[x] == dep[b.to] + 1 && b.cap > b.flow) {
int tmp = augment(b.to, min(a, b.cap - b.flow));
flow += tmp;
a -= tmp;
b.flow += tmp;
e[G[x][i]^1].flow -= tmp;
if (!a) return flow;
}
}
if (!(--gap[dep[x]])) dep[s] = cnt+1;
++gap[++dep[x]], cur[x] = 0;
return flow;
}
ll maxFlow_ISAP()
{
cnt = n; //Num_of_nodes -> cnt
init();
ll ans = 0;
while (dep[s] <= cnt) ans += augment(s, INF);
return ans;
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w, i << 1);
}
printf("%lld\n", maxFlow_ISAP());
return 0;
}
感谢支持!
【模板】网络最大流(EK、Dinic、ISAP)(网络流)/洛谷P3376的更多相关文章
- 【最大流ISAP】洛谷P3376模板题
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 网络最大流(EK)
以前在oi中见到网络流的题都是直接跳过,由于本蒟蒻的理解能力太弱,导致网络流的学习不断推迟甚至被安排在了tarjan之后,原本计划于学习完最短路后就来学网络流的想法也随之破灭,在看完众多大佬 的博客后 ...
- 【洛谷 p3376】模板-网络最大流(图论)
题目:给出一个网络图,以及其源点和汇点,求出其网络最大流. 解法:网络流Dinic算法. 1 #include<cstdio> 2 #include<cstdlib> 3 #i ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
- 洛谷P3376【模板】网络最大流 ISAP
这篇博客写得非常好呀. 传送门 于是我是DCOI这一届第一个网络流写ISAP的人了,之后不用再被YKK她们嘲笑我用Dinic了!就是这样! 感觉ISAP是会比Dinic快,只分一次层,然后不能增广了再 ...
- 洛谷 P3376 【【模板】网络最大流】
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui. ...
- 『题解』洛谷P3376 【模板】网络最大流
Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...
- 洛谷——P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 洛谷 P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 洛谷 P3376【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
随机推荐
- Java中的位运算符 &、|、^、~、<< 和 >>
一.& 按位与运算符 5 & 3 = 1 5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101 3转换为二进制:0000 0000 0000 ...
- 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器
前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开始尝到智能家居的甜头了,这两东西有没有用我不知道,但是没事的时候掏出手机瞄两眼,看着就让人很安心( ̄︶ ̄). 于是懒惰的我开始琢磨把给植物浇 ...
- DeWeb : 制作图片轮换效果
演示:http://www.web0000.com/slide.dw源代码:http://www.web0000.com/media/source/slide.zip一.新建一个DLL二.除第一行外, ...
- (一)lamp 环境搭建之编译安装apache
apache的编译安装: 安装步骤大概参考:http://www.cnblogs.com/iyoule/archive/2013/10/24/3385540.html 简单的将分为三步: (1)安装a ...
- 使用Visual Studio 2019将ASP.NET Core发布为linux-arm64程序
前言 前段时间入手了一台树莓派4B,一直闲置未使用,最近工作需要,要在上面跑下.NET Core程序,由于树莓派4B使用的是ARM架构,并且支持64位操作系统,为了充分发挥树莓派性能,我的这台树莓派安 ...
- 『学了就忘』Linux基础命令 — 29、关机和重启
目录 1.sync数据同步 2.shutdown命令 3.reboot命令 4.halt和poweroff命令 5.init命令 1.sync数据同步 sync命令的基本信息如下: 命令名称:sync ...
- pip切换源
pip国内的一些镜像 阿里云http://mirrors.aliyun.com/pypi/simple/ 中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/ ...
- 【编译原理】LL1文法语法分析器
上篇文章[编译原理]语法分析--自上向下分析 分析了LL1语法,文章最后说给出栗子,现在补上去. 说明: 这个语法分析器是利用LL1分析方法实现的. 预测分析表和终结符以及非终结符都是针对一个特定文法 ...
- 数据库炸了----我就重启了一下啊(Communications link failure)
重启数据库后,数据库大部分时间连不上了:连续请求不会报错,请求间隔时间稍微长一点就会报错报错如图: com.mysql.cj.jdbc.exceptions.CommunicationsExcepti ...
- Spring @Component生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致
正确注入方式: @Autowired private TFeeMapper TFeeMapper; 错误注入方式 @Autowired private TFeeMapper tFeeMapper; 这 ...