SPFA

SPFA

 

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

using namespace std;

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

const int INF = 1e9; //无穷值看情况改变
struct node{
    int v, w;
};

//复杂度 ≈ O(2E),有时复杂度会很高接近与Bellman-ford O(VE)

bool SPFA(int s, int n, vector<vector<node > >& E ){
    queue<int > que;  //队列
    vector<int > cnt(n + 1, 0); //更新次数
    vector<bool > vis(n + 1, false); //是否在队列
    vector<int > d(n + 1, INF); //距离数组
    d[s] = 0; //初始点赋值为0
    que.push(s); //压入队列
    vis[s] = true; //在队列

    while(!que.empty()){
        int u = que.front();
        que.pop();
        vis[u] = false; //出队列,不在队列
        for(auto e : E[u]){
            if(d[e.v] > d[u] + e.w){
                d[e.v] = d[u] + e.w;
                if(!vis[e.v]){ //v不在队列
                    vis[e.v] = true;
                    que.push(e.v);
                    if(++cnt[e.v] >= n) return true; //更新次数判断是否有负环
                }
            }
        }
    }
    return false;
}

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

int main(){

    solve();

    return 0;
}

 

posted @ 2020-05-21 19:23  SummerMingQAQ  阅读(98)  评论(0编辑  收藏  举报