P3385-[模板]负环【SPFA】

版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/88071662

正题


题目大意

求点1可不可以走到负环。


解题思路

c n t i cnt_i 表示到 i i 的最短路经过了多少个点,然后求若 c n t i n cnt_i\geq n 且这条路是负数那么就有负环。


c o d e code

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=2100,M=3100;
struct node{
    int to,next,w;
}a[M*2];
queue<int> q;
int n,m,tot,ls[N],f[N],cnt[N],T;
bool v[N];
void addl(int x,int y,int w)
{
    a[++tot].to=y;
    a[tot].next=ls[x];
    a[tot].w=w;
    ls[x]=tot;
}
bool spfa()
{
    memset(f,0x3f,sizeof(f));
    memset(cnt,0,sizeof(cnt));
    q.push(1);cnt[1]=1;
    f[1]=0;v[1]=1;
    while(!q.empty()){
        int x=q.front();v[x]=0;
        q.pop();
        for(int i=ls[x];i;i=a[i].next){
            int y=a[i].to;
            if(f[x]+a[i].w<f[y]){
                f[y]=f[x]+a[i].w;
                cnt[y]=cnt[x]+1;
                if(cnt[y]>=n&&a[i].w<0)
                    return true;
                if(!v[y]){
                    v[y]=1;
                    q.push(y);
                }
            }
        } 
    }
    return false;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    { 
        memset(ls,0,sizeof(ls));
        tot=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            addl(x,y,w);
            if(w>=0) addl(y,x,w);
        }
        if(spfa()) printf("YE5");
        else printf("N0");
        putchar('\n');
    }
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/88071662