【洛谷 3385】负环

题目描述

暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索

寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环。

输入格式

第一行一个正整数T表示数据组数,对于每组数据:

第一行两个正整数N M,表示图有N个顶点,M条边

接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)

输出格式

共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。

输入输出样例

输入 #1
2
3 4
1 2 2
1 3 4
2 3 1
3 1 -3
3 3
1 2 3
2 3 4
3 1 -8
输出 #1
N0
YE5

说明/提示

n\leq 2000n2000

m\leq 3000m3000

-10000\leq w\leq 1000010000w10000

T\leq 10T10

建议复制输出格式中的字符串。 本题数据感谢@negiizhao的精心构造,请不要使用玄学算法 本题数据有更新

 

 

题解:蓝题不难系列……spfa判负权环啦。貌似可以水过去

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
const int N=30005;
const int M=200010;
int T,st=1;
int cntt,n,m;
bool flag,v[N];
int d[N],cnt[N];
int head[N],tot;
struct node{
    int to;
    int next;
    int val;
}e[M];
void add(int x,int y,int z){
    e[++cntt].to=y;
    e[cntt].val=z;
    e[cntt].next=head[x];
    head[x]=cntt;
}
bool spfa(){
    queue<int> q;
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    d[st]=0;v[st]=1,cnt[st]=1;
    q.push(st);
    while(q.size()){
        int x=q.front(); q.pop(); v[x]=0;
        for(int i=head[x];i;i=e[i].next){
            int y=e[i].to;
            if(d[y]>d[x]+e[i].val){
                d[y]=d[x]+e[i].val;
                cnt[y]=cnt[x]+1;
                if(cnt[y]>n) return 1;
                if(!v[y]) { v[y]=1; q.push(y); }
            }
        }
    }
    return 0;
}
int main(){
    freopen("3385.in","r",stdin);
    freopen("3385.out","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        memset(head,0,sizeof(head));
        tot=0; int x,y,w;
        for(int i=1;i<=m;i++){
            scanf("%d %d %d",&x,&y,&w);
            add(x,y,w);
            if(w>=0) add(y,x,w);
        }
        if(spfa()) puts("YE5");
        else puts("N0");
    }
}

 

posted @ 2019-11-12 17:16  #Cookies#  阅读(151)  评论(0编辑  收藏  举报