Luogu P3385 【模板】负环

传送门

为了方便以后抄自己代码

如果一个点入队次数超过n次,说明有负环

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#define MogeKo qwq
using namespace std;
const int maxn = 2e5+10;
const int INF = 0x3f3f3f3f;
int t,m,n,x,y,z,cnt;
int head[maxn],to[maxn],nxt[maxn],w[maxn];
int dis[maxn],num[maxn];
bool vis[maxn];

void add(int x,int y,int z) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
    w[cnt] = z;
}

bool SPFA() {
    queue <int> q;
    q.push(1);
    dis[1] = 0;
    vis[1] = true;
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(int i = head[u]; i; i = nxt[i]) {
            int v = to[i];
            if(dis[v] <= dis[u]+w[i]) continue;
            if(++num[v] > n) return true;
            dis[v] = dis[u]+w[i];
            if(!vis[v]) {
                q.push(v);
                vis[v] = true;
            }
        }
    }
    return false;
}

void init() {
    memset(num,0,sizeof(num));
    memset(head,0,sizeof(head));
    memset(nxt,0,sizeof(nxt));
    memset(vis,0,sizeof(vis));
    memset(dis,INF,sizeof(dis));
}

int main() {
    scanf("%d",&t);
    while(t--) {
        init();
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            if(z >= 0) add(y,x,z);
        }
        if(SPFA()) printf("YE5
");
        else printf("N0
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/mogeko/p/11257806.html