Bellman-ford

Bellman-ford

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

#define ll long long
#define pb push_back
#define fi first
#define se second

const int INF = 2e9;   //无穷值看情况改变
struct node{
    int u, v, w;
};
 //注意:bellman-ford算法能判负环,但可能存在一个负环,起点无法到达这个负环
 //n = 4  m = 3
 // 2 3 -1
 // 3 4 -1
 // 4 2 -1
 //这个图有负环,但是如果从起点1出发,则没法到达这个负环,则代表没有负环
 //SPFA则解决了这个问题,SPFA从起点出发,遍历到它能到达的点,然后继续更新
 //复杂度: O(VE)
bool Bellman(int s, int n, vector<node >& E){
    vector<int > d(n + 1, INF); //n个点初始化
    d[s] = 0; //开始
    for(int i = 1; i < n; ++i){  // n - 1次
        for(auto e : E){ //遍历所有边
            d[e.v] = min(d[e.v], d[e.u] + e.w);
        }
    }
    //小优化:对于每次扫边判断有没有进行更新操作,如果一次扫边没出现一个更新操作则直接退出循环(用flag = 0,1判断)
    for(auto e : E){
        if(d[e.v] > d[e.u] + e.w) return true; //还可以松弛,有负环
    }
    return false;
}

void solve(){
    int T;
    scanf("%d", &T);
    while(T--){ //T组
        int n, m;
        scanf("%d%d", &n, &m); //点数   边数
        vector<node > E;
        int u, v, w; //出发点  抵达点 权值
        for(int i = 0; i < m; ++i){
            scanf("%d%d%d", &u, &v, &w);
            E.pb({u, v, w});
        }
        //从1出发
        if(Bellman(1, n, E)) printf("YES
");
        else printf("NO
");
    }
}

int main(){

    solve();

    return 0;
}
原文地址:https://www.cnblogs.com/SSummerZzz/p/12932156.html