AcWing 852. spfa判断负环--java
原题链接
简单
作者:
Acvv_scl
,
2021-03-09 00:30:16
,
所有人可见
,
阅读 200
思路
- 注意增加一个cnt数组 用来记录每个点 更新的次数
- 注意 要将所有的点都加入到队列中 ,因为 可能存在局部独立负环;
import java.util.*;
public class Main{
static int INF=Integer.MAX_VALUE>>1;
static int N=2010;
static int M=100010;
static int n;
static int m;
//
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 index;
static int []dist=new int[N];
static boolean[]st=new boolean[N];
//每个点更新的次数;如果存在cnt[i]>=n的时候 就存在负环
static int []cnt=new int[N];
static Queue<Integer>q=new LinkedList();
static void add(int a,int b,int c){
w[index]=c;e[index]=b;ne[index]=h[a];h[a]=index++;
}
static {
Arrays.fill(h,-1);
}
static boolean spfa(){
//注意 这个千万不能放到初始化里面;注意n的值此时没有输入 默认为0
//需要将所有的点都加入到队列中;可能有局部的点自己是一个负环
for(int i=1;i<=n;i++){
q.add(i);
st[i]=true;
}
while(q.size()>0){
int t=q.poll();
st[t]=false;
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>dist[t]+w[i]){
dist[j]=dist[t]+w[i];
//更新 每个点更新的次数;
cnt[j]=cnt[t]+1;
if(cnt[j]>=n)return true;
if(!st[j]){
st[j]=true;
q.add(j);
}
}
}
}
return false;
}
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
for(int i=1;i<=m;i++){
add(sc.nextInt(),sc.nextInt(),sc.nextInt());
}
if(spfa()){
System.out.println("Yes");
}else{
System.out.println("No");
}
}
}