hdu 2544【java】最短路

本文介绍了一种基于索引优先队列实现的最短路径算法,用于解决从起点到终点寻找最短时间路径的问题。通过读取输入创建图结构,并使用优先队列更新节点之间的最短距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最短路

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 64242    Accepted Submission(s): 28125


Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

 

Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
 

Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
 

Sample Input
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
 

Sample Output
3 2
 

运用了一下索引优先队列,当然写索引优先队列会费些时间,但是只是花些时间而已


public static void main(String args[]){
		
		Main main=new Main();
		while(true){
			int end=scan.nextInt();
			int num=scan.nextInt();
			if(end==num&&num==0){
				break;
			}
			main.start(end ,num);
		}
		
			
		
		
	}
	
	static Scanner scan=new Scanner(System.in);
	
	public void start(int end,int num){
		
		
		Graph g=new Graph(end);
		
		for(int i=0;i<num;i++){
			
			int a=scan.nextInt();
			int b=scan.nextInt();
			int c=scan.nextInt();
			g.add(new Edge(a,b,c));
			
		}
		int max=100000000;
		
		MinPQ<Double> pq=new MinPQ<Double>(end);
		double distTo[]=new double[end+1];
		for(int i=0;i<distTo.length;i++){
			
			distTo[i]=max;
			
		}
		distTo[1]=0;
		pq.insert(1,distTo[1]);
		while(!pq.isEmpty()){
			
			int a=pq.delete();
			for(Edge i:g.array[a]){
				
				if(distTo[i.other(a)]>distTo[a]+i.weight){
					distTo[i.other(a)]=distTo[a]+i.weight;
					if(!pq.continues(i.other(a))) pq.charge(i.other(a), distTo[i.other(a)]);
					else{
						
						pq.insert(i.other(a), distTo[i.other(a)]);
					}
				}
				
			}
			
		}
		
		System.out.println((int)distTo[end]);
		
	}
	
	class MinPQ<E extends Comparable>{
		
		E pq[];//比较数
		
		
		int size;
		int positive[];
		int lose[];
		
		public boolean isEmpty(){
			
			return size==0;
		}
		
		public void charge(int i,E key){
			
			pq[i]=key;
			swim(lose[i]);
			sink(lose[i]);
			
		}
		
		public boolean continues(int i){
			return lose[i]==-1;
			
			
			
		}
		
		public MinPQ(int vSize) {
			
			this.pq = (E[]) new Comparable[vSize+1];
			this.positive=new int[vSize+1];
			this.lose=new int[vSize+1];
			Arrays.fill(lose, -1);
			
			
		}

		public void insert(int k,E e){
			
			
			positive[++size]=k;
			pq[k]=e;
			lose[k]=size;
			
			swim(size);
			
		}
		
		public int delete(){
			
			int index=positive[1];
			exch(1,size--);
			sink(1);//
			pq[positive[size+1]]=null;//其实这地方开始就有点糊了。
			lose[positive[size+1]]=-1;
			
			return index;
			
		}
		
		public boolean less(int i,int j){
			int a=0;
			try{
				a=pq[positive[i]].compareTo(pq[positive[j]]);
			}catch(ArrayIndexOutOfBoundsException e){
				
			}
			return a==1;
			
		}
		
		public void exch(int i,int j){
			
			int d=positive[i];
			positive[i]=positive[j];
			positive[j]=d;
			lose[positive[i]]=i;
			lose[positive[j]]=j;
			
		}
		
		public void swim(int k){
			
			while(k>1){
		
				if(!less(k,k/2)) break;
				
				exch(k,k/2);
				k=k/2;
			}
			
			
		}
		public void sink(int k){
			
			
			
			while(2*k<=size){
				int j=2*k;
			
				if(j<size&&less(j,j+1)) j++;
				if(!less(j,k)) break;
				exch(j,k);
				k=j;
				
			}
			
		}
		
	}
	
	class Point implements Comparable<Point>{
		
		int v;
		long weight;
		public Point(int v, long weight) {
			super();
			this.v = v;
			this.weight = weight;
		}
		@Override
		public int compareTo(Point o) {
			if(weight>o.weight){
				return 1;
			}else{
				return -1;
			}
			
		}
		@Override
		public String toString() {
			return "Point [v=" + v + ", weight=" + weight + "]";
		}
		
		
	}
	
	class Graph{
		int vSize;
		ArrayList<Edge> array[];
		public Graph(int vSize) {
			super();
			this.vSize = vSize;
			array=(ArrayList<Edge>[])new ArrayList[vSize+1];
			for(int i=0;i<array.length;i++){
				
				array[i]=new ArrayList<Edge>();
				
			}
		}
		public void add( Edge e){
			
			array[e.v].add(e);
			array[e.w].add(e);
			
		}
		
		
		
	}
	class Edge {
		
		int w;
		int v;
		int weight;
		public Edge(int w, int v, int weight) {
			super();
			this.w = w;
			this.v = v;
			this.weight = weight;
		}
		public int other(int point){
			
			if(v==point) return w;
			else return v;
			
		}
		
		
		
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值