给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。

请你判断图中是否存在负权回路。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

输入格式

第一行包含整数n和m。

接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出格式

如果图中存在负权回路,则输出“Yes”,否则输出“No”。

数据范围

1n2000
1m10000
图中涉及边长绝对值均不超过10000。

输入样例:

3 3
1 2 -1
2 3 4
3 1 -4

输出样例:

Yes

代码:
//邻接表存储
//n=1e5,不能用邻接表

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
        static final int N=100005, INF=0x3f3f3f3f;
        static int h[]=new int[N];
        static int e[]=new int[N];
        static int ne[]=new int[N];
        static int w[]=new int[N];
        static int dis[]=new int[N];
        static int cnt[]=new int[N];//
        static boolean vis[]=new boolean[N];
        static int n,m,idx;
        static void add(int a,int b,int c){
                e[idx]=b;
                w[idx]=c;
                ne[idx]=h[a];
                h[a]=idx++;
        }
        static boolean spfa(){
                ArrayDeque<Integer> q = new ArrayDeque<Integer>();
                Arrays.fill(dis, INF);
                dis[1]=0;
                for(int i=1;i<=n;i++){//不能只加入1了,因为每个点都要判断一下,负权回路并不是每个点都能进入的
                    q.offer(i);
                    vis[i]=true;
                }
                while(!q.isEmpty()){
                        int t=q.poll();
                        vis[t]=false;//不在队列中,置为false
                        for(int i=h[t];i!=-1;i=ne[i]){
                                int j=e[i];
                                if(dis[j]>dis[t]+w[i]){
                                        dis[j]=dis[t]+w[i];
                                        cnt[j]=cnt[t]+1;
                                        if(cnt[j]>=n) return true;//如果存在负权回路,路径那么会一直执行更新,就是在这个负环中转圈;对图中的点,它最多经过n-1条边到达另一个点,所以大于等于n,肯定是存在负权回路
                                        if(!vis[j]){
                                                vis[j]=true;
                                                q.offer(j);
                                        }
                                }
                        }
                }
                return false;
        }
        public static void main(String[] args) {
                Scanner scan=new Scanner(System.in);
                n=scan.nextInt();
                m=scan.nextInt();
                Arrays.fill(h, -1);
                while(m-->0){
                        int a=scan.nextInt();
                        int b=scan.nextInt();
                        int c=scan.nextInt();
                        add(a,b,c);
                }
                if(spfa()) System.out.println("Yes");
                else System.out.println("No");
        }
}

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄