数据结构与算法学习笔记----SPFA判断负环

数据结构与算法学习笔记----SPFA判断负环

@@ author: 明月清了个风

@@ first publish time: 2024.12.19

ps⭐️思路在题目里面

Acwing 852. spfa判断负环

原题链接(852. spfa判断负环 - AcWing题库)

给定一个 n n n个点 m m m条边的有向图,图中可能存在重边和自环,边权可能为负数。

请你判断图中是否存在负权回路。

输入格式

第一行包含三个整数 n n n, m m m。

接下来 m m m行,每行包含三个整数 x x x、 y y y、 z z z,表示存在一条从点 x x x到点 y y y的有向边,边长为 z z z。

输出格式

如果图中存在 负权回路,则输出 Yes,否则输出 No

数据范围

1 ≤ n ≤ 2000 1 \leq n \leq 2000 1≤n≤2000,

1 ≤ m ≤ 10000 1 \leq m \leq 10000 1≤m≤10000,

图中涉及边长均不超过10000。

思路

spfa判断负环的逻辑和bellman-ford一样,n n n个点的图最长的路径中最多只有 n − 1 n-1 n−1条边 ,因此如果有一条路径能被更新 n n n次就说明有负环存在

注意点

  1. 队列中初始要加入所有点,因为并不知道负环在哪条路径上。
  2. 距离不用初始化,都是 0 0 0即可,负权可以更新距离。

代码

cpp 复制代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 2010, M = 10010;

int dist[N];
int cnt[N];
bool st[N];
int h[N], e[M], w[M], ne[M], idx;
int n, m;

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

bool spfa()
{
    queue<int> q;
    
    for(int i = 1; i <= n; i ++)
    {
        q.push(i);
        st[i] = true;
    }
    
    while(q.size())
    {
        int t = q.front();
        q.pop();
        
        st[t] = false;
        
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                cnt[j] = cnt[t] + 1;
                if(cnt[j] >= n) return true;
                if(!st[j])
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
    
    return false;
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    
    for(int i = 0; i < m; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
    }
    
    if(spfa()) puts("Yes");
    else puts("No");
    
    return 0;
}
相关推荐
通信小呆呆1 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick1 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee1 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn861 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e1 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨1 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
闪闪发亮的小星星1 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq1 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan1 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
阿米亚波1 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm