POJ-1860(最短路问题,Bellman-Ford算法判正圈)

Currency Exchange

POJ-1860

  • 这题其实是最短路问题的变形,但是这里不用求解最短路,而是求解路径中是否存在正圈。如果存在正圈则说明兑换后的货币可以一直增加,否则不能实现通过货币转化来增加财富。
  • 这和经典的使用Bellman-Ford判断是否存在负权也有不同的地方,这里需要在松弛方程中,改变判断的条件。
package POJ;
import java.util.*;

public class POJ_1860 {
	static int n,m,s;
	static double money;
	static int edges;//边的数量
	static class edge{
		public int from,to;
		public double rate,commisions;
		edge(){}
		edge(int from,int to,double rate,double commisions){
			this.from=from;this.to=to;this.rate=rate;this.commisions=commisions;
		}
	};
	static edge []es;
	static double []d;
	static boolean BellmanFord() {
		d[s]=money;
		for(int i=1;i<n;i++) {//下标从1开始
			boolean flag=false;
			for(int j=0;j<edges;j++) {
				edge e=es[j];
				if(d[e.to]<(d[e.from]-e.commisions)*e.rate) {
					flag=true;
					d[e.to]=(d[e.from]-e.commisions)*e.rate;
				}
			}
			if(!flag)
				return false;
		}
		for(int j=0;j<edges;j++) {
			edge e=es[j];
			if(d[e.to]<(d[e.from]-e.commisions)*e.rate) {
				return true;
			}
		}
		return false;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		n=cin.nextInt();
		m=cin.nextInt();
		s=cin.nextInt();
		money=cin.nextDouble();
		es=new edge[2*m];
		d=new double[n+1];
		int j=0;
		for(int i=0;i<m;i++) {
			int from,to;
			double r,m,r1,m1;
			from=cin.nextInt();to=cin.nextInt();r=cin.nextDouble();m=cin.nextDouble();r1=cin.nextDouble();m1=cin.nextDouble();
			es[j++]=new edge(from,to,r,m);
			es[j++]=new edge(to,from,r1,m1);
		}
		edges=j;
		if(BellmanFord())
			System.out.println("YES");
		else System.out.println("NO");
	}
}

``
上一篇:第2章基本概念8、编程计算第一、二、三月还贷剩余金额


下一篇:基于梯度下降的变压器铁心柱横截面设计算法