POJ-3259(最短路+Bellman-Ford算法判负圈)

Wormholes

POJ-3259

  • 这题是最短路问题中判断是否存在负圈的模板题。
  • 判断负圈的一个关键就是理解:如果在图中不存在从s可达的负圈,最短路径不会经过一个顶点两次。while循环最多执行v-1次。
  • 这题还需要注意的是输入的w条边的权值是负值,因为这是虫洞边。
package POJ;
import java.util.*;
public class POJ_3259 {
	static int f,n,m,w;
	public int from,to;
	public double rate,commisions;
	static int edges;//边数
	static class edge{
		public int from,to,se;
		edge(){}
		edge(int from,int to,int se){
			this.from=from;this.to=to;this.se=se;
		}
	};
	static edge []es;
	static int []d;//distance数组
	static boolean BellmanFord() {	
		Arrays.fill(d, 0);
		for(int i=0;i<n;i++) {//下标从1开始
			for(int j=0;j<edges;j++) {
				edge e=es[j];
				if(d[e.to]>d[e.from]+e.se) {
					d[e.to]=d[e.from]+e.se;
					if(i==n-1)
						return true;
				}
			}

		}
		return false;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		f=cin.nextInt();
		while(f!=0) {
			n=cin.nextInt();
			m=cin.nextInt();
			w=cin.nextInt();
			es=new edge[2*m+w];
			d=new int[n+1];
			int k=0;
			int from,to,se;
			for(int j=0;j<m;j++) {
				from=cin.nextInt();
				to=cin.nextInt();
				se=cin.nextInt();
				es[k++]=new edge(from,to,se);
				es[k++]=new edge(to,from,se);
			}
			for(int j=0;j<w;j++) {
				from=cin.nextInt();
				to=cin.nextInt();
				se=cin.nextInt();
				es[k++]=new edge(from,to,-se);
			}
			edges=k;
			if(BellmanFord())
				System.out.println("YES");
			else System.out.println("NO");
			f--;
		}
	}
}

posted @ 2020-05-10 17:26  Garrett_Wale  阅读(201)  评论(0编辑  收藏  举报