AOJ0155 Spider Jin

問題リンク Spider Jin

  • 解法

最短路問題です。
ビルをノードとして、距離Rが50以下であるような2つのビルi, jの間にコストRの辺を張り、あとはダイクストラです。
ビルsからtへ辿りつける場合、最短経路がユニークに決まることが保証されており、この問題はその移動経路を出力しないとだめです。
double d[i]を始点からビルiまでの最短距離(d[s]=0)
int pre[i]をビルiまでの最短経路においてiの直前に訪れていたビルの番号(pre[s]=-1)
をしまうものとします。
ダイクストラ法でd[i]が更新されるタイミングでpre[i]も更新します。最短経路が求まったら、pre[t]を芋づる式にたどって行くと、経路の逆順が得られます。

  • ソース
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;

//Spider Jin
public class AOJ0155 {

	static double[] d;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true){
			int n = sc.nextInt();
			if(n==0)break;
			int[] id = new int[n];
			int[][] p = new int[n][2];
			Map<Integer, Integer> ref = new HashMap<Integer, Integer>();
			for(int i=0;i<n;i++){
				id[i] = sc.nextInt();
				p[i][0] = sc.nextInt();
				p[i][1] = sc.nextInt();
				ref.put(id[i], i);
			}
			double[][] cost = new double[n][n];
			for(int i=0;i<n;i++){
				for(int j=i+1;j<n;j++){
					double r = Math.hypot(p[i][0]-p[j][0], p[i][1]-p[j][1]);
					if(r<=50) cost[i][j] = cost[j][i] = r;
					else cost[i][j] = cost[j][i] = Integer.MAX_VALUE;
				}
			}
			int m = sc.nextInt();
			while(m--!=0){
				int s = ref.get(sc.nextInt());
				int g = ref.get(sc.nextInt());
				int[] pre = new int[1001];
				d = new double[n];
				Arrays.fill(d, Integer.MAX_VALUE);
				d[s] = 0;
				pre[s] = -1;
				PriorityQueue<Integer> q = new PriorityQueue<Integer>(n, new Comparator<Integer>() {
					public int compare(Integer o1, Integer o2) {
						return d[o1]-d[o2]<0?-1:d[o1]-d[o2]>0?1:0;
					}
				});
				q.add(s);
				String ans = "NA";
				while(!q.isEmpty()){
					int v = q.poll();
					if(v==g){
						int ID = v;
						ans = "";
						while(ID!=s){
							ans = " "+id[ID]+ans;
							ID = ref.get(pre[id[ID]]);
						}
						ans = id[s]+ans;
						break;
					}
					for(int i=0;i<n;i++){
						if(cost[v][i]!=Integer.MAX_VALUE){
							double c = d[v] + cost[v][i];
							if(c < d[i]){
								d[i] = c;
								pre[id[i]] = id[v];
								q.add(i);
							}
						}
					}
				}
				System.out.println(ans);
			}
		}
	}
}