注意事项

一,判断有无负环时候不需要初始会dist数组,但是当我们判断是否存在以某个点为起点的负环,则需要把,qu.push(pos),dist[pos] = 0,其他置为memset(dist,0x3f,sizeof dist),负环可能以任意一点为起点,所以就需要把所有起点放入队列之中!

二,判断存在条件是cnt[j] >= n,这里cnt[j] 应该是入队的次数,即st == [false]之后,而不是松弛的次数!

P3385 【模板】负环
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
const int N = 4e4+9;
int idx,h[N],e[N],ne[N],w[N];
bool st[N];
int qu[N],dist[N],cnt[N];
void add(int a,int b,int c)
{
    e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
}

bool spfa()
{
    memset(cnt,0,sizeof cnt);
    memset(dist,0x3f,sizeof dist);
    memset(st,false,sizeof st);
    int hh = 0,tt = 0;
    qu[tt++] = 1;
    dist[1] = 0;
    while(hh != tt)
    {
        int t = qu[--tt];
        st[t] = false;
        for(int i=h[t]; ~i; i=ne[i])
        {
            int j = e[i];
            if(dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if(!st[j])
                {
                    cnt[j] = cnt[t] + 1;
                    if(cnt[j] >= n) return true;
                    st[j] = true;
                    qu[tt++] = j;
                }
            }
        }
    }
    return false;
}

int main()
{
    //freopen("P3385_9.in","r",stdin);
    //freopen("out.txt","w",stdout);
    int _;
    cin >> _;
    while(_--)
    {
        memset(h,-1,sizeof(h));
        idx = 0;
        cin >> n >> m;
        for(int i=1; i<=m; i++)
        {
            int a,b,c;
            cin >> a >> b >> c;
            add(a,b,c);
            if(c >= 0)
            {
                add(b,a,c);
            }
        }
        if(spfa()) puts("YES");
        else puts("NO");
    }
    return 0;
}