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; }