POJ2135 - Farm Tour(最小费用流 + 模板 + SPFA + Dijstra)

算法笔记:Dinic最大流和SPFA费用流 先利用BFS对残余网络分层 一个节点的深度,就是源点到它最少要经过的边数。 利用BFS对残余网络分层,分完层后,利用DFS从前一层向后一层反复寻找增广路。 这里写图片描述 分完层后,从源点开始,用DFS从前一层向后一层反复寻找增广路(即要求DFS的每一步都必须要走到下一层的节点)。 因此,前面在分层时,只要进行到汇点的层次数被算出即可停止,因为按照该DFS的规则,和汇点同层或更下一层的节点,是不可能走到汇点的。 DFS过程中,要是碰到了汇点,则说明找到了一条增广路径。此时要增加总流量的值,消减路径上各边的容 阅读详情

题目链接:

http://poj.org/problem?id=2135


题目大意:

现在有 N 个节点,有M条边,要从 1 走到 N 然后再回到 1 。要求走的边不能重复,求最短路径。


解题过程:

之前看了最小费用最大流然后一直没有做题,于是找了一个模板题来刷,对着板子敲上去居然一次AC,然后又改了下最短路的算法,AC。


题目分析:

算是一个隐含的最小费用最大流,设每条边的容量为1,花费为路径长度。那么所求的就是一个从起点 1 到终点 N 流量为 2 的流的最小费用流。

这里用的是最短增广路算法。

AC代码:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

const int MAX = 1123, INF = 0x3f3f3f3f;
int N, M;

struct Node{
    int to, cap, cost, rev;
    Node(int to, int cap, int cost, int rev):to(to), cap(cap), cost(cost), rev(rev){}
};

vector<Node> edge[MAX];
int dist[MAX], vis[MAX], prevv[MAX], preve[MAX];

void add_edge(int from, int to, int cap, int cost) {
    edge[from].push_back(Node(to, cap, cost, edge[to].size()));
    edge[to].push_back(Node(from, 0, -cost, edge[from].size()-1));
}

int min_cost_flow(int s, int t, int f) {
    int rst = 0;
    //循环到到达了f流量
    while (f > 0) {
        memset(dist, INF, sizeof(dist));
        queue<int> q;
        q.push(s);
        vis[s] = 1;
        dist[s] = 0;
        while (!q.empty()) {
            int u = q.front();
            for (int i = 0; i < edge[u].size(); i++) {
                Node& e = edge[u][i];
                if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) {
                    dist[e.to] = dist[u] + e.cost;
                    prevv[e.to] = u;
                    preve[e.to] = i;
                    if (!vis[e.to]) {
                        q.push(e.to);
                        vis[e.to] = 1;
                    }
                }
            }
            q.pop();
            vis[u] = 0;
        }
        if (dist[t] == INF) return -1;

        //最路径上最小流量
        int d = f;
        for (int u = t; u != s; u = prevv[u]) {
            d = min(d, edge[prevv[u]][preve[u]].cap);
        }
        //剩余的流量
        f -= d;
        //计算费用
        rst += d * dist[t];
        //修改路上所经过的边的容量
        for (int u = t; u != s; u = prevv[u]) {
            Node& e = edge[prevv[u]][preve[u]];
            e.cap -= d;
            edge[u][e.rev].cap += d;
        }
    }
    return rst;
}

int main() {
    scanf("%d %d", &N, &M);
    for (int i = 0; i < M; i++) {
        int from, to, cost;
        scanf("%d %d %d", &from, &to, &cost);
        add_edge(from, to, 1, cost);
        add_edge(to, from, 1, cost);
    }
    //求流量为2的最小费用
    int ans = min_cost_flow(1, N, 2);
    printf("%d\n", ans);
}

居然可以AC的Dijstra代码:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

const int MAX = 1123, INF = 0x3f3f3f3f;
int N, M;

struct Node{
    int to, cap, cost, rev;
    Node(int to, int cap, int cost, int rev):to(to), cap(cap), cost(cost), rev(rev){}
};

vector<Node> edge[MAX];
int dist[MAX], vis[MAX], prevv[MAX], preve[MAX];

void add_edge(int from, int to, int cap, int cost) {
    edge[from].push_back(Node(to, cap, cost, edge[to].size()));
    edge[to].push_back(Node(from, 0, -cost, edge[from].size()-1));
}

int min_cost_flow(int s, int t, int f) {
    int rst = 0;
    while (f > 0) {
        memset(dist, INF, sizeof(dist));
        queue<int> q;
        q.push(s);
        vis[s] = 1;
        dist[s] = 0;
        while (!q.empty()) {
            int u = q.front();
            for (int i = 0; i < edge[u].size(); i++) {
                Node& e = edge[u][i];
                if (e.cap > 0 && dist[e.to] > dist[u] + e.cost) {
                    dist[e.to] = dist[u] + e.cost;
                    prevv[e.to] = u;
                    preve[e.to] = i;
                    if (!vis[e.to]) {
                        q.push(e.to);
                        vis[e.to] = 1;
                    }
                }
            }
            q.pop();
            vis[u] = 0;
        }
        if (dist[t] == INF) return -1;

        int d = f;
        for (int u = t; u != s; u = prevv[u]) {
            d = min(d, edge[prevv[u]][preve[u]].cap);
        }
        f -= d;
        rst += d * dist[t];
        for (int u = t; u != s; u = prevv[u]) {
            Node& e = edge[prevv[u]][preve[u]];
            e.cap -= d;
            edge[u][e.rev].cap += d;
        }
    }
    return rst;
}

int main() {
    scanf("%d %d", &N, &M);
    for (int i = 0; i < M; i++) {
        int from, to, cost;
        scanf("%d %d %d", &from, &to, &cost);
        add_edge(from, to, 1, cost);
        add_edge(to, from, 1, cost);
    }
    int ans = min_cost_flow(1, N, 2);
    printf("%d\n", ans);
}
POJ 2135(费用流基础题) POJ 2135题目大意有N个点M条双向边的图,求从起点1到终点N的两条边不相交的路径,要求这两条路径长度的总和最小,输出最小长度分析肯定不能通过贪心的方法先求一条再求一条。我们可以换一种方式来描述问题:有两个人要从节点1走到节点2,要求他们不能走同一条道路,问他们走的总路程的最小值是多少。费用流问题(MCMF)是解决每条边有容量限制,每条边上有单位流量的花费,求在一定流量下的最小花费的问题。通过重 阅读详情

相关推荐

CH32V IAP跳转避坑指南:为什么你的APP跳不过去?从mstatus寄存器配置到函数属性详解

本文深入解析CH32V系列MCU的IAP跳转机制,从mstatus寄存器配置到函数属性优化,详细讲解如何避免APP跳转失败。文章涵盖地址准备、模式切换、跳转执行等关键步骤,并提供调试技巧与实战案例,帮助开发者快速解决CH32V IAP跳转中的常见问题。

weixin_30955617的博客 139

网络流(二) 最小费用最大流问题

上篇我们讲解了最大流问题,那什么是最小费用最大流呢?听名字就可以看出,我们要在满足最大流的同时找到达成最大流的最小费用。对于一个网络流,最大流是一定的,但是组成最大流的费用是可以不同的,这里就有了在最大流网络上产生的费用流网络,就有了最小花费问题。

这里是阿安的博客 8299

keil软件调试(Debug)仿真教程(软件调试和硬件调试的区别)及常用调试按键详解

单片机的调试分为两种,一种是使用软件模拟调试,第二种是硬件调试,两种调试方式各有不同,软件模拟调试有误差,而硬件调试,借用仿真器调试是嵌入式开发中常用方法。

weixin_51624736的博客 3万+

网络流----最小费用最大流(EK+SPFA)

该网络中总花费最小的最大流称为最小费用最大流,总花费最大的最大流称为最大费用最大流,二者合称费用流模型,即在最大流的前提下考虑费用的最值。

AC__dream的博客 2178

Claude code-review 插件深度解析:AI 驱动的智能代码审查系统

Claude Code Review 插件深度解析:AI 驱动的智能代码审查系统 该插件通过多 Agent 并行工作方式自动审查 PR,采用置信度评分机制(80+分保留)过滤误报,确保高质量反馈。核心功能包括: 5个专业化 Agent 并行审查(规范合规性、bug检测、历史分析等) 8步工作流程:从资格检查到 GitHub 评论发布 创新性置信度评分系统(0-100分),严格过滤7类误报 结合 CLAUDE.md 规范和历史 PR 评论实现一致性审查 技术亮点: 多 Agent 架构(Haiku/Sonne

虚心若愚 2263

DLL导出函数名隐藏实战:三种方法保护代码安全

在Windows软件开发中,动态链接库(DLL)的导出函数名是模块间通信的关键标识,也是逆向工程的重要突破口。理解PE文件格式中的导出表结构是掌握DLL工作原理的基础,它记录了函数地址、名称和序号的映射关系。通过隐藏或混淆这些导出名称,可以有效增加代码分析的难度,提升软件的知识产权保护和安全性。这一技术在软件保护、游戏反作弊和安全组件中具有重要价值。本文聚焦DLL导出函数名隐藏,结合Dependencies工具分析,详细解析仅序号导出、导出转发器和运行时动态修改三种实用方案,为开发者提供从原理到实践的完整指

weixin_29315091的博客 307

费用流模板——SPFA

先解释一下费用流:对于一个网络, 我们可能会有多组最大流, 现在我们给每条边附上一个费用系数, 每条边产生的费用 = 这条边的流量 × 这条边的费用系数,常见的问题是求最小费用最大流。

Cold_Chair的博客 1003

T分布和T检验的理解,Python代码实现T检验的计算

每天学习一点,每天进步一点。 声明:本人所有的原创,都是自己在学习过程中的记录点滴,不一定都是对的,肯定也会有一些错误的想法。所以大家看一看就好,不可尽信。当然也欢迎指出。 T分布 定义,有来自标准正态分布的样本X ~ N(0,1),和来自卡方n分布的Y ~ X2(n), 那么有 Z= X/√(Y/n) 成为符合自由度为n的T分布 我们用Python代码画一下他的图形 # 给一个自由度,返回这个自由度的卡方分布 X²(n) def product(n): n = np.ceil(n).astype

PY_smallH的博客 8485

[模版] spfa费用流

#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <string> #include <algorith.

HeartWine的博客 317

从矩阵理论角度理解偏最小二乘回归,以及在脑科学中(脑影像与行为、基因表达的关系)的应用举例

偏最小二乘法 (PLS) 是一种多元数据驱动的统计技术,旨在提取表示最大大脑行为关联的潜在变量(或潜在成分 latent components [LC])。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 975

数据挖掘在人力资源分析中的实战案例

在当今竞争激烈的商业环境中,人力资源管理对于企业的成功至关重要。有效的人力资源管理能够提高员工绩效、降低员工流失率、优化人才招聘等。而数据挖掘技术为人力资源管理提供了强大的工具,通过对大量人力资源数据的分析,可以发现潜在的规律和模式,为企业的决策提供有力支持。本文的目的是通过实际案例展示数据挖掘在人力资源分析中的具体应用,涵盖员工绩效预测、人才招聘筛选、员工流失分析等多个方面。通过详细的案例分析,帮助读者理解数据挖掘技术在人力资源管理中的实际操作和应用价值。

移动开发前沿的博客 489

最小费用最大流问题与算法实现(Bellman-Ford、SPFA、Dijkstra)

Bellman-Ford、SPFA、改进的Dijkstra三种算法解决最小费用最大流问题以及相关代码的实现。

不积跬步无以至千里 7万+

LLaMA Factory多卡微调的实战教程(持续更新)

本文主要介绍了LLaMA Factory多卡微调的实战教程(持续更新),希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 配置环境 2.1 安装虚拟环境 2.2 安装依赖库 2.3 模型选型与下载 2.4 配置多卡环境 3. 运行代码 3.1 构建训练数据 3.2 修改配置文件 3.3 微调 3.3.1 zero3微调 3.3.2 启动API 3.3.3 模型测试

herosunly的博客 25万+

【POJ - 2135 】【最小费用最大流】【裸】【1->n->1不重复路的最小值】

http://poj.org/problem?id=2135 【题意】 求1-&gt;n-&gt;1不重复路的最短路 【题解】最小费用最大流的模板题                最小费用最大流--&gt;多次s'p'fa--&gt;满足最大情况下,用spfa找可行流的最短路径                建图:源点s:0,汇点t:n+1                1.add(s...

running_acmer的博客 597

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

汽车加油行驶问题

分层图,k只有10,每个k一层图 跑费用流,但容量为1,所以就是SPFA # include <bits/stdc++.h> # define RG register # define IL inline # define ID(a, b, c) ((c) * N * N + (a - 1) * N + b) # define Fill(a, b) memset(a, b, sizeof(a

Cyhlnj 807

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

网络流之费用流模型

超详细证明!费用流的相关模型及应用,SPP算法、二分图、最小费用最大流

GROZAX的博客 969

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

最小费用最大流-SPFA-多路增广

背景 在最近的模拟赛当中,我碰到了一题二分图最大权匹配的题,建图比较简单,因为是IOI赛制,所以可以爆OJ,然后呢,打了一发普通的spfa费用流,跑的很慢诶,只拿了70分,都有人AC了呢。那天的讲题,好像说写KM(二分图最大权完美匹配的一种算法)就能过,但是呢,新的东西学还是需要一段时间的,但要订正的话,emm,还是学一学优化的spfa费用流吧,即多路增广一下,事实证明这是能过的。 算法介

zhouyuheng2003的博客 2865

最小费用流 用SPFA实现

/* (1)找到一条从源点到达汇点的“距离最短”的路径,“距离”使用该路径上的边的单位费用之和来衡量。 (2)然后找出这条路径上的边的容量的最小值f,则当前最大流max_flow扩充f,同时当前最小费用min_cost扩充 f*min_dist(s,t)。 (3)将这条路径上的每条正向边的容量都减少f,每条反向边的容量都增加f。 (4)重复(1)--(3)直到无法找到从源点到达汇点的路径。...

skykone1的博客 443

POJ - 2135最小费用流

题目链接:http://poj.org/problem?id=2135 今天学习最小费用流。模板手敲了一遍。 产生了一个新的问题:对于一条无向边,这样修改了正向边容量后,反向边不用管吗? 后来想了想,得出了个结论。路径所选的边只会包括正反中的一条。 #include <iostream> #include <cstdio> #include &lt...

weixin_33722405的博客 147

ZKW,SPFA费用流模板

费用流比较常用的做法有两种:SPFA费用流和ZKW费用流两种费用流的基本做法相同:找到费用最小的路,不断增广到不能增广为止 正确性很显然,因为每次都找费用最小的路,所以费用一定最小,因为增广到不能增广才停止,所以一定是最大流SPFA费用流打起来和理解起来很简单,就是通过SPFA找到费用最小的路,并把这条路上的每条边的流量都减去这整条路的流量最小值,不断循环直到找不到增广路位置 缺点也很显然:在稠

Jacky35 629

费用流模板——EK+SPFA实现的最小费用最大流

算法原理 用两个字的高度概括——贪心~ 用一句话的概括:每一次通过spfa找到花费最小的可行流,然后进行增广,直到残量网络中,源点不能达到汇点。 其实还是通过代码理解比较好。 code 这里1是源点,n是汇点。 每次的读入四个数:有向边的两个结点+容量+费用 #include&lt;bits/stdc++.h&gt; using namespace std; inline i...

蒟蒻柴犬首相的博客 814

费用流SPFA版

#include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f

Dan__ge的博客 1345

最小费用最大流(spfa增广)——模板整理

这个算法好像没名字。。就是每次spfa增广。 时间复杂度O(n*m^2*3)?#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn=5005,maxe=100005; int n,m,nxt[maxe],S,T,fir[maxn],tot=

Lynstery's blog 1214

最大流(SAP)及最小费用最大流(SPFA)模版

最小费用最大流 模版 一、最小费用最大流的模型 在保证流量最大的前提下,所需的费用最小,这就是最小费用最大流问题.   带有费用的网络流图: G=(V,E,C,W) V:顶点; E:弧;C:弧的容量;W:单位流量费用。 任意的弧对应非负的容量c[i,j]和单位流量费用w[i,j]。满足: ① 流量f是G的最大流。 ② 在f是G的最大流的前提下,流的费用最小。

代码改变世界,keep coding。 3823

poj2135网络流费用入门

poj2135网络流费用流入门 题目链接:http://poj.org/problem?id=2135 题目部分 题意介绍: 主人公要从1号走到第N号点,再重N号点走回1号点,同时每条路只能走一次。 这是一个无向图。输入数据第一行是2个是N和M。N为点的数量,M为路径个数。 接下来M行是边的数据,每行输入3个数,边的两个端点a,b和边的长度v。 要你输出来回最短的路径长度。 题目确保存在来

formicary的专栏 2079
上一篇: HDU4725 - The Shortest Path in Nya Graph (Dijstra + 建图)
下一篇: 常见错误清单(长期更新)
ACM_Fish
博客等级 码龄10年 69粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值