Problem:
スパイダー人
正義のヒーロー「スパイダー人」は、腕からロープを出してビルからビルへ飛び移ることができます。しかし、ロープが短いので自分からの距離が 50 以下のビルにしか移動できません。それより遠くのビルに移動するには、一旦別のビルに飛び移らなくてはなりません。
ビルの数
n
、
n
個のビルの情報、スパイダー人の移動開始位置及び目的地を入力とし、その移動の最短経路を出力するプログラムを作成してください。どのようにビルを経由しても目標のビルに移動できない場合は NA と出力してください。各ビルは点として扱い、最短距離で移動するビルの経由方法が２つ以上存在することはないものとします。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。
各データセットは以下の形式で与えられます。
n
b
1
x
1
y
1
b
2
x
2
y
2
:
b
n
x
n
y
n
m
s
1
g
1
s
2
g
2
:
s
m
g
m
１行目にビルの数
n
(1 ≤
n
≤ 100)、続く
n
行に
i
番目のビルのビル番号
b
i
(1 ≤
b
i
≤
n
)、そのビルのx座標とy座標を表す整数
x
i
,
y
i
(-1000 ≤
x
i
,
y
i
≤ 1000) が空白区切りで与えられます。
続く行に移動情報の個数
m
(1 ≤
m
≤ 100)、続く
m
行に
i
番目の移動情報が与えられます。各移動情報として、移動を開始するビルの番号
s
i
と目的地ビルの番号
g
i
が空白区切りで与えられます。
データセットの数は 10 を超えません。
Output
入力データセットごとに次の形式で出力します。
i
行目に
i
番目の移動情報に対する経路または NA を１行に出力します。各経路は以下の形式で出力します。
s
i
br
i1
br
i2
...
g
i
br
ij
は
i
番目の移動情報における、
j
番目に経由するビルの番号を表します。
Sample Input
4
1 0 0
2 30 0
3 60 40
4 0 60
2
1 3
1 4
22
1 0 0
2 150 40
3 30 20
4 180 150
5 40 80
6 130 130
7 72 28
8 172 118
9 50 50
10 160 82
11 90 105
12 144 131
13 130 64
14 80 140
15 38 117
16 190 90
17 60 100
18 100 70
19 130 100
20 71 69
21 200 110
22 120 150
1
1 22
0
Output for the Sample Input
1 2 3
NA
1 3 9 20 11 6 22

Submitted solutions:

code_snippet: #include <iostream>
#include <complex>
#include <vector>
#include <algorithm>
using namespace std;

#define INF 10e6
#define X real()
#define Y imag()
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
typedef complex<double> P;


int n; //ビルの数
P build[1001]; //ビルの座標
double graph[1001][1001];//距離グラフ
double d[1001];  //最短距離
int prev[1001];  //経路
bool used[1001]; //	訪問済み

void initial(){
	for(int i=0;i<1001;i++)
		for(int j=0;j<1001;j++)
			graph[i][j]=(abs(build[i]-build[j]))<=50.0?abs(build[i]-build[j]):INF;
	return ;
}

void dijkstra(int s){
	fill(d,d+1001,INF);
	fill(used,used+1001,false);
	fill(prev,prev+1001,-1);
	d[s]=0;
	
	while(true){
		int v=-1;
		for(int u=0;u<n;u++){
			if(!used[u]&&(v==-1||d[u]<d[v]))v=u;
		}
		if(v==-1)
			break;
		used[v]=true;
		for(int u=0;u<n;u++){
			if(d[u]>d[v]+graph[u][v])
				d[u]=d[v]+graph[u][v],prev[u]=v;
		}
	}
	return ;
}

vector<int> get_path(int t){
	vector<int> path;
	for(;t!=-1;t=prev[t])path.push_back(t);
	reverse(path.begin(),path.end());
	return path;

}

int main(){
	int tem,m;
	while(cin >> n,n){
		for(int i=0;i<n;i++)
			cin >>tem,cin >>build[tem-1].X>> build[tem-1].Y;
		initial();
		cin >> m;
		for(int i=0;i<m;i++){
			int s,g,c;
			vector<int> root;
			cin >> s >> g;
			dijkstra(s-1);
			if(d[g-1]>=INF)
				cout << "NA" << endl;
			else{
				root=get_path(g-1);
				c=0;
				EACH(j,root)
					cout<< (c? " ":"") << (*j)+1,c++;
				cout << endl;
			}
		}
	}

return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11072
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<cmath>

using namespace std;

int n, m, b, i, j, x, y, s, g;
vector <pair <int, int> > map(1000);
vector <int> from(1000, 1001);

double dist(int mi, int j) {
  double d =  sqrt(1.0 * (map[j].first - map[mi].first) * (map[j].first - map[mi].first) + (map[j].second - map[mi].second) * (map[j].second - map[mi].second));
  if(d <= 50) return d;
  else        return 100000000;
} 

double dik(){
  int f[1000] = {};
  int mi = s;
  vector <int> cost(1000, 100000000);
  cost[mi] = 0;
  
  for(i = 0; i < 1000; i++) {
    f[mi] = 1;
    
    for(j = 0; j < 1000; j++)
      if(!f[j] && map[j].first != 100000000 && cost[j] > cost[mi] + dist(mi, j)) {
        cost[j] = cost[mi] + dist(mi, j);
        from[j] = mi;
      }
    int min = 200000000;
    for(j = 0; j < 1000; j++)
      if(!f[j] && min > cost[j]) min = cost[mi = j];
  }
  return cost[g];

}


int main(){
  while(cin >> n, n != 0) {
    for(i = 0; i < 1000; i++) {
      map[i].first = 100000000; map[i].second = 100000000;
    }
    
    while(n--){
      cin >> b >> x >> y;  b--;  x--;  y--;
      map[b].first = x; map[b].second = y;
    }
    
    cin >> m;
    while(m--) {
      cin >> s >> g; s--; g--;
      int ans[1000] = {};
      for(i = 0; i < 1000; i++) from[i] = 1001;
      if(dik() != 100000000) {
	
	for(i = g,j = 0; i < 1000; j++){
	  ans[j] = from[i] + 1;
	  i = from[i];
	}
	//	cout << ans[0] << ' ' << ans[1]  <<' '<< ans[2]  << ' ' << ans[3] << endl;
	for(i = j - 2; i >= 0; i--)  cout << ans[i] << ' ';
	cout << g + 1 << endl;
      }
      
      else cout << "NA" << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 1220
final_rank: 2

code_snippet: #include "bits/stdc++.h"

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define INF 999999999

pii d[2000];
bool used[2000];
double pass[2000][2000];
int n;

void dijk(int s){
    rep(i,2000)d[i]=pii(INF,-1);
    rep(i,2000)used[i]=false;
    d[s]=pii(0,-1);
    
    while (1) {
        int v=-1;
        rep(u,n){
            if( !used[u]&&(v==-1||d[u].first<d[v].first) )v=u;
        }
        
        if(v==-1)break;
        
        used[v]=true;
        
        rep(u,n){
            if( d[u].first>d[v].first+pass[v][u] )
                d[u] = pii( d[v].first+pass[v][u] , v );
        }
    }
}


int main(){
    while(cin>>n){
        if(n==0)break;
        
        rep(i,2000)rep(j,2000) pass[i][j]=INF;
        int b[2000],x[2000],y[2000];
        double res;
        rep(i,n){
            cin>>b[i]>>x[i]>>y[i];
        }
        rep(i,n){
            rep(j,n){
                if(i==j)
                    pass[b[i]-1][b[i]-1]=0;
                else if( ( res=sqrt( (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) ) )<=50+1e-9  ){
                    pass[b[i]-1][b[j]-1]=res;
                    pass[b[j]-1][b[i]-1]=res;
                }
            }
        }
        int m;
        cin>>m;
        rep(i,m){
            int s,g;
            cin>>s>>g;
            s--,g--;
            dijk(s);
            if(d[g].first==INF){cout<<"NA"<<endl;continue;}
            int tmp = g;
            vector<int> ans;
            while(tmp!=s){
                ans.pb(tmp);
                tmp = d[tmp].second;
            }
            ans.pb(s);
            reverse(all(ans));
            rep(i,ans.size()){
                if(i!=0)cout<<" ";
                cout<<ans[i]+1;
            }
            cout<<endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 32508
final_rank: 4

code_snippet: #include<iostream>
#include<complex>
#include<map>
#include<vector>
#include<algorithm>
#define INF 20000000
using namespace std;
typedef complex<double> P;
map<int,P>data;
double gr[1200][1200];


int prev[1200];
double d[1200];
int used[1200];
void dijkstra(int s){
	fill(d,d+1200,INF);
	fill(used,used+1200,false);
	fill(prev,prev+1200,-1);
	d[s]=0;
	while(true){
		int v=-1;
		for(int u=0;u<1200;u++){
			if(!used[u]&&(v==-1||d[u]<d[v]))v=u;
		}
		if(v==-1)break;
		used[v]=true;
		
		for(int u=0;u<1200;u++){
			if(d[u]>d[v]+gr[v][u]){
				d[u]=d[v]+gr[v][u];
				prev[u]=v;
			}
		}
	}
}
vector<int>get_path(int t){
	vector<int>path;
	for(;t!=-1;t=prev[t])path.push_back(t);
	reverse(path.begin(),path.end());
	return path;
}
int main(){
	int n;
		while(cin>>n &&n){
		fill((double*)gr,(double*)gr+1200*1200,INF);
		for(int i=0;i<n;i++){
			int b,x,y;
			cin>>b>>x>>y;
			data[b].real()=x;
			data[b].imag()=y;
		}
		for(map<int,P>::iterator itr=data.begin();itr!=data.end();itr++){
			for(map<int,P>::iterator it=data.begin();it!=data.end();it++){
				if(abs(itr->second-it->second)<=50 &&abs(itr->second-it->second)>0){
					gr[itr->first][it->first]=abs(itr->second-it->second);
				}
			}
		}
	
		int m;
		cin>>m;
		for(int i=0;i<m;i++){
			int a,b;
			cin>>a>>b;
			dijkstra(a);
			if(d[b]==INF){
				cout<<"NA"<<endl;
				continue;
			}
			else{
		
				vector<int>ans;
				ans=get_path(b);
				for(int i=0;i<ans.size();i++){
					if(i)cout<<" ";
					cout<<ans[i];
				}
				cout<<endl;
			}
		}
	}
}
accuracy: 1
time_ms: 190
memory_kb: 12504
final_rank: 5

code_snippet: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < j; ++i)
#define FOR(i, j, k) for(int i = j; i < k; ++i)
#define P complex<double>
#define Y real()
#define X imag()
const double INF = (1 << 16);
const int N = 1010;

class C{
  public:
    double dis;
    int now;
    vector<int> visited;
    C(double _d, int _n, vector<int> _v){
      dis = _d;
      now = _n;
      visited = _v;
    }
    bool operator>(const C &c) const { return dis > c.dis; }
};

int main() {
  int n;
  while(cin >>n && n){
    vector< pair<int, P> > building(n);
    REP(i, n){
      int a, b;
      cin >>building[i].first >>a >>b;
      building[i].second = P(a, b);
    }
    vector< vector<double> > v(N, vector<double>(N, INF));
    REP(i, n){
      REP(j, n){
        double d = abs(building[i].second - building[j].second);
        if(d <= 50.0) v[building[i].first][building[j].first] = d;
      }
    }

    int m; cin >>m;
    REP(z, m){
      int s, g; cin >>s >>g;
      priority_queue<C, vector<C>, greater<C> > open;
      vector<int> tmp(N, INF);
      tmp[s] = 0;
      open.push( C(0.0, s, tmp) );
      vector<double> closed(N, INF);
      C ans = C(0.0, -1, vector<int>());

      while(!open.empty()){
        C now = open.top();
        open.pop();

        //debug
        //cout <<now.dis <<", " <<now.now <<", ";
        //REP(i, N) REP(j, N) if(now.visited[j] == i) cout <<j <<" ";
        //cout <<endl <<"---------" <<endl;

        if(now.now == g){
          ans = now;
          break;
        }
        if(closed[now.now] <= now.dis) continue;
        closed[now.now] = now.dis;

        REP(i, N){
          if(now.visited[i] != INF || v[now.now][i] == INF) continue;
          now.visited[i] = now.dis + v[now.now][i];
          open.push( C(now.dis + v[now.now][i], i, now.visited) );
          now.visited[i] = INF;
        }
      }

      if(ans.now == -1) cout <<"NA" <<endl;
      else{
        vector<int> ans_v;
        REP(i, N) REP(j, N) if(ans.visited[j] == i) ans_v.push_back(j);
        cout <<ans_v[0];
        FOR(i, 1, ans_v.size()) cout <<" " <<ans_v[i];
        cout <<endl;
      }

    }
  }
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 9384
final_rank: 3