poj1062

设计算法:dijkstra(最短路径)

题目大意:部落中每个人手里有一件物品都有一个给定的价值,这些物品可以用某些指定的其他物品加上一定的金币来交换,年轻的探险家为了以最少的金币获得国王手中的物品(也就是过往的女儿),注意部落有森严的等级制度,超过等级限制的两个人不能直接或者间接交易,年轻的探险家可以不受等级限制即第一次可以与任何人交易。

题目分析:建立最短路径算法的模型,将交换体系中的人看做是一个结点,结点之间的交换价值就是结点之间的权重,规定一个原本不存在的结点0使它到每个结点的权重为各个结点的自身价值,那么题目就变成了求结点0到结点1的最短路径(在等级限制下)

代码如下:

public class Main_1062 {

	static int limt;
	static int n;
	static int[] p=new int[101];
	static int[] r=new int[101];
	static int[][] ex=new int[101][101];//ex[i][j]:表示用j替代i需要付出的金币
	static int[] dis=new int[101];
	static final int MAX=0x7FFFFFFF;
	static boolean used[]=new boolean[101];
	
	public static void main(String[] args) {
		
		Scanner in=new Scanner(System.in);
		
		limt=in.nextInt();
		n=in.nextInt();
		
		int x=0;
		for(int i=1;i<=n;i++){
			p[i]=in.nextInt();
			r[i]=in.nextInt();
			x=in.nextInt();
			for(int j=0;j<x;j++){
				ex[i][in.nextInt()]=in.nextInt();
			}
		}
		
		for(int i=1;i<=n;i++){
			ex[i][0]=p[i];
		}

		solve();
	}
	
	static void dijkstra(){
		
		Arrays.fill(dis, MAX);
		dis[0]=0;//源结点
		used[0]=false;
		
		int x=1;int min=MAX;
		for(int i=1;i<=n;i++){
			
			min=MAX;

			//第一步找到最小dis的结点
			for(int j=0;j<=n;j++){
				
				if(!used[j] && dis[j]<min){
					min=dis[j];
					x=j;
				}
			}
			
			used[x]=true;
			
			//更新与最小dis结点相邻且未被标记的结点的dis
			for(int j=1;j<=n;j++){
				if(!used[j] && ex[j][x]>0 && dis[j]>dis[x]+ex[j][x]){
					dis[j]=dis[x]+ex[j][x];
					//System.out.println("dis["+j+"]="+dis[j]);
				}
			}
			
		}	
	}
	
	//由于有了等级的限制,所以只有上面的是不够的,因为路径可能不通
	
	static void solve(){
		
		int min_dis=ex[1][0];
		
		for(int i=1;i<=n;i++){
			
			for(int j=1;j<=n;j++){
				if(r[j]>=r[i] && r[j]<=r[i]+limt){//枚举出可用的结点
					used[j]=false;
				}else {
					used[j]=true;
				}
			}
			if(used[1]==false){
				dijkstra();
			}
			
			if(dis[1]<min_dis){
				min_dis=dis[1];
			}
		}
		
		System.out.println(min_dis);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值