AcWing算法进阶课-1.17.1费用流

news/2024/7/15 18:04:09 标签: 算法, c++, 网络流, 费用流, 图论

算法进阶课整理

CSDN个人主页:更好的阅读体验

Start

原题链接
题目描述

给定一个包含 n n n 个点 m m m 条边的有向图,并给定每条边的容量和费用,边的容量非负。

图中可能存在重边和自环,保证费用不会存在负环。

求从 S S S T T T 的最大流,以及在流量最大时的最小费用。

输入格式

第一行包含四个整数 n , m , S , T n,m,S,T n,m,S,T

接下来 m m m 行,每行三个整数 u , v , c , w u,v,c,w u,v,c,w,表示从点 u u u 到点 v v v 存在一条有向边,容量为 c c c,费用为 w w w

点的编号从 1 1 1 n n n

输出格式

输出点 S S S 到点 T T T 的最大流和流量最大时的最小费用。

如果从点 S S S 无法到达点 T T T 则输出 0 0

数据范围

2 ≤ n ≤ 5000 2≤n≤5000 2n5000,

1 ≤ m ≤ 50000 1≤m≤50000 1m50000,

0 ≤ c ≤ 100 0≤c≤100 0c100,

− 100 ≤ w ≤ 100 -100 \le w \le 100 100w100

S ≠ T S≠T S=T


算法步骤

费用流算法本质上是 EK 算法,只不过将找增广路的 BFS 算法替换为了 SPFA 算法

  1. 找到一条费用最少(最多)的增广路径
  2. 更新残量网络
  3. 累加最大流量
算法时间复杂度 O ( n m f ) O(nmf) O(nmf)

AC Code

C + + \text{C}++ C++

#include <iostream>
#include <cstring>

using namespace std;

const int N = 5010, M = 100010;
const int INF = 1e9;

int n, m, S, T;
int h[N], e[M], ne[M], f[M], w[M], idx;
int q[N], d[N], pre[N], lim[N];
bool st[N];

inline void add(int a, int b, int c, int d)
{
	e[idx] = b, f[idx] = c, w[idx] = d, ne[idx] = h[a], h[a] = idx ++ ;
	e[idx] = a, f[idx] = 0, w[idx] = -d, ne[idx] = h[b], h[b] = idx ++ ;
}

bool spfa()
{
	int hh = 0, tt = 1;
	memset(d, 0x3f, sizeof d);
	memset(lim, 0, sizeof lim);
	q[0] = S, d[S] = 0, lim[S] = INF;

	while (hh != tt)
	{
		int t = q[hh ++ ];
		if (hh == N) hh = 0;
		st[t] = false;
		for (int i = h[t]; ~i; i = ne[i])
		{
			int j = e[i];
			if (d[j] > d[t] + w[i] && f[i])
			{
				d[j] = d[t] + w[i];
				pre[j] = i, lim[j] = min(f[i], lim[t]);
				if (!st[j])
				{
					st[j] = true;
					q[tt ++ ] = j;
					if (tt == N) tt = 0;
				}
			}
		}
	}
	return lim[T] > 0;
}

void EK(int& flow, int& cost)
{
	while (spfa())
	{
		int t = lim[T];
		flow += t, cost += t * d[T];
		for (int i = T; i != S; i = e[pre[i] ^ 1])
			f[pre[i]] -= t, f[pre[i] ^ 1] += t;
	}
}

int main()
{
	int a, b, c, d;
	memset(h, -1, sizeof h);

	scanf("%d%d%d%d", &n, &m, &S, &T);
	while (m -- )
	{
		scanf("%d%d%d%d", &a, &b, &c, &d);
		add(a, b, c, d);
	}

	int flow = 0, cost = 0;
	EK(flow, cost);
	printf("%d %d\n", flow, cost);

	return 0;
}

228aa7bed3e021faf24cf8560d3e47bb.gif

最后,如果觉得对您有帮助的话,点个赞再走吧!


http://www.niftyadmin.cn/n/5288081.html

相关文章

时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现SSA-CNN-LSTM麻雀算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-LSTM麻雀算法优化卷积长短…

当windows系统缺失.dll文件

当windows系统缺失.dll文件 在这里下载缺失的那个文件 把下载好的文件放到你的系统路径。它的默认路径是在&#xff1a; Windows7 放到C:\Windows\System32

GoogleNet网络分析与demo实例

参考自 up主的b站链接&#xff1a;霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频这位大佬的博客 Fun_机器学习,pytorch图像分类,工具箱-CSDN博客 1. GoogLeNet网络详解 GoogLeNet在2014年由Google团队提出&#xff08;与VGG网络同年&#xff0c;注意GoogLeNet中的L大…

7.仿若依后端系统业务实践

目录 概述项目实践mybatis 反向生成代码有覆盖问题解决pom.xmlbootstrap.ymlapplication.ymlmaven测试各种校验问题实践单个属性校验级联属性校验接口实体类测试结果自定义关联属性校验接口

Python 爬虫之下载歌曲(一)

爬取某酷音乐平台歌曲 文章目录 爬取某酷音乐平台歌曲前言一、基本流程二、代码编写三、效果展示总结 前言 老是爬视频有点乏味&#xff0c;换个口味。今天出个爬歌曲的。后续由易到难也出个相关的系列教程。 一、基本流程 打开某酷网站播放某个歌曲&#xff0c;复制这个歌曲…

前端---表单提交

1. 表单属性设置 <form>标签 表示表单标签&#xff0c;定义整体的表单区域 action属性 设置表单数据提交地址method属性 设置表单提交的方式&#xff0c;一般有“GET”方式和“POST”方式, 不区分大小写 2. 表单元素属性设置 name属性 设置表单元素的名称&#xff0c…

HuTool工具类常用方法汇总

HuTool工具类常用方法汇总 hutool官方文档地址 引入需要依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all

【支持向量机】SVM线性可分支持向量机学习算法——硬间隔最大化支持向量机及例题详解

支特向量机(support vector machines, SVM)是一种二类分类模型。它的基本模型是定义在特征空间上的间隔最大的线性分类器。包含线性可分支持向量机、 线性支持向量机、非线性支持向量机。 当训练数据线性可分时&#xff0c;通过硬间隔最大化学习线性分类器&#xff0c; 即为线性…