洛谷 P1339:[USACO09OCT] Heat Wave G ← Bellman-Ford 算法

【题目来源】

https://www.luogu.com.cn/problem/P1339

【题目描述】
有一个 n 个点 m 条边的无向图,请求出从 s 到 t 的最短路长度。

【输入格式】
第一行四个正整数 n,m,s,t。 接下来 m 行,每行三个正整数 u,v,w,表示一条连接 u,v,长为 w 的边。

【输出格式】
输出一行一个整数,表示答案。

【输入样例】
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

【输出样例】
7

【数据范围】
对于 100% 的数据,1≤n≤2500,1≤m≤6200,1≤w≤1000。

【算法分析】
● Bellman-Ford 算法使用边集数组存图,而非邻接表。这是因为 Bellman-Ford 在每一轮迭代中,都需要遍历图中全部边执行松弛操作,无需查询某个顶点的出边。而邻接表的核心优势,是快速获取单个顶点的邻接边,但这项能力在 Bellman-Ford 算法中完全用不到。因此,邻接表额外的索引结构自然成为冗余。反观边集数组,它仅存储每条边自身的信息,结构极简,恰好适配 Bellman-Ford 算法的执行逻辑。

● 包含 n 个顶点的图,其最短路径一定是简单路径(路径中不会重复经过同一个顶点,不含任何环),即最多包含 n-1 条边。所以,Bellman-Ford 算法最多只需要松弛 n-1 轮。
(1)算法的第 k 轮松弛,作用是求出"最多经过 k 条边"能够得到的最短距离。第 1 轮更新仅用 1 条边可达的最短路,第 2 轮更新最多 2 条边的最短路,以此类推。当完成 n-1 轮松弛后,所有简单路径对应的最短距离都已经被更新完成。
(2)如果执行完 n-1 轮之后,仍然还有边可以继续松弛,就说明图中存在"负环"。即可以不断环绕这个环,无限降低路径总权值,不存在有限的最短路径。

● 本题为无向图。无向边 u-v 等价于两条方向相反的有向边:u → v 与 v → u。因此在使用 Bellman‑Ford 算法的边集数组存图时,读入一条无向边,需要同时存入这两条有向边,才能完整表达双向连通关系。

【算法代码】

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int N=3e3+5;
const int M=2e4+5;
const int inf=0x3f3f3f3f;
int dis[N];

struct edge {
    int u,v,w;
} e[M];

int n,m,s,t;

void bellman() {
    memset(dis,inf,sizeof dis);
    dis[s]=0;
    for(int i=1; i<=n-1; i++) {
        bool flag=0;
        for(int j=1; j<=2*m; j++) {
            int u=e[j].u,v=e[j].v,w=e[j].w;
            if(dis[u]!=inf && dis[v]>dis[u]+w) {
                dis[v]=dis[u]+w;
                flag=1;
            }
        }
        if(!flag) break;
    }
}

int main() {
    cin>>n>>m>>s>>t;
    int cnt=0;
    for(int i=1; i<=m; i++) {
        int u,v,w;
        cin>>u>>v>>w;
        e[++cnt]= {u,v,w};
        e[++cnt]= {v,u,w};
    }
    bellman();
    cout<<dis[t];

    return 0;
}


/*
in:
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

out:
7
*/

【参考文献】

https://www.luogu.com.cn/problem/solution/P1339

相关推荐
SelectDB技术团队3 小时前
ClickHouse 存日志的能力边界:并发、检索与 trace 回放的实测对照
数据结构·数据库·clickhouse·日志分析·apache doris·日志存储
垆边人似月.3 小时前
华为算法题:最长连续递增子序列的变
数据结构·算法·leetcode
w_zero_one3 小时前
链表(2)
java·数据结构·链表
kukubuzai4 小时前
二分查找系列一
数据结构·算法·leetcode
wzdark4 小时前
算法与数据结构教学的可视化新模式探索4
数据结构
hzxpaipai5 小时前
企业官网后台怎么设计?从产品分类、参数到资料下载的数据结构
数据结构
不会就选b14 小时前
算法日常・每日刷题--<贪心>25
数据结构·算法
Cccp.12317 小时前
【leetcode】(七)前缀树和贪心算法
数据结构·leetcode·贪心算法
Logic10120 小时前
C语言/数据结构位运算题解:异或XOR找出多任务下载器中的“独特下载速度“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质