AcWing算法进阶课-1.17.1费用流

2023-12-26 07:12
文章标签 算法 进阶 acwing 费用 1.17

本文主要是介绍AcWing算法进阶课-1.17.1费用流,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法进阶课整理

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

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

这篇关于AcWing算法进阶课-1.17.1费用流的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538515

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时