/*
突然发现hdu的oj数据很强大,在zoj可以过的代码,在hoj就wrong 开始让我有点纳闷
题目很简单就是路劲的保存有点麻烦,最麻烦的是字典序那个
这几天题目虽然做的很少,而且所有的代码基本都是自己一个一敲出来的,很少一出错就baidu之类的
鉴戒是要有的,可是。。。。这个暑假只AC
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>//stack 是好东西啊
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 0x3ffffff;
const int N = 1005;
int cost[N][N];
int path[N];
int c1[N];
int c2[N];
int dis[N];
int v[N];
bool hash[N];
int n;
void small(int start, int j, int pre)
{//这里差不都是xwc的方法
stack<int>s;
int len1 = 0, len2 = 0;
int tt = j;
while(tt != start)
{
s.push(tt);
tt = path[tt];
}
s.push(start);
while(!s.empty())
{
c1[len1++] = s.top();
s.pop();
}
s.push(j);
//s.push(pre);
tt = pre;
while(tt != start)
{
s.push(tt);
tt = path[tt];
}
s.push(start);
while(!s.empty())
{
c2[len2++] = s.top();
s.pop();
}
int min1 = min(len1 ,len2);
for(int i = 0; i < min1; i++)
{
if(c1[i] == c2[i])
continue;
else if(c1[i] > c2[i])
path[j] = pre;
else
break;
}
//if()
}
void Dijsktra(int start, int end)
{
int i, j, k;
memset(hash, false, sizeof(hash));
for(i = 1; i <= n; i++)
{
dis[i] = cost[start][i];
path[i] = start;
}
dis[start] = 0;
hash[start] = true;
for(i = 1; i <= n; i++)
{
int d = MAX;
k = start;
for(j = 1; j <= n; j++)
{
if(!hash[j] && dis[j] < d)
{
k = j;
d = dis[j];
}
}
hash[k] = true;
if( MAX == dis[k])
break;
for(j = 1; j <= n; j++)
{
if(!hash[j] && dis[j] > dis[k] + cost[k][j] + v[k] )
{
dis[j] = dis[k] + cost[k][j] + v[k];
//if(k < path[j])
path[j] = k;
}//如果路劲相等输出字典序最小的
else if(!hash[j] && dis[j] == dis[k] + cost[k][j] + v[k])
{//这里没有加hash[j] 就在hdu oj wrong 在zoj就过了,忒假了
small(start, j, k);
}
}
}
printf("From %d to %d :/n", start, end);
stack <int> s;
//s.push(end);
//int tt = path[end];
int tt = end;
while(tt != start)
{
s.push(tt);
tt = path[tt];
}
s.push(start);
printf("Path: ");
int e = s.top();
s.pop();
printf("%d", e);
while(!s.empty())
{
int e = s.top();
s.pop();
printf("-->%d", e);
}
printf("/n");
/*
for(i = len ; i >= 0; i--)
{
if(i != 0)
printf("%d-->", ctrl[i]);
else
printf("%d/n", ctrl[i]);
}
*/
//for(i = 1; i <= n; i++)
//printf("%d ", path[i]);
printf("Total cost : %d/n/n", dis[end]);
}
int main()
{
//int df[N];
while(scanf("%d", &n) != EOF && n)
{
int i, j, k;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
scanf("%d", &cost[i][j]);
if(cost[i][j] == -1)
cost[i][j] = MAX;
}
for(i = 1; i <= n; i++)
scanf("%d", &v[i]);
int a, b;
while(1)
{
scanf("%d %d", &a, &b);
if(a == -1 && b == -1)
break;
Dijsktra(a ,b);
}
}
return 0;
}
/*
4
0 2 -1 1
2 0 2 -1
-1 2 0 1
1 -1 1 0
9 2 9 4
1 3
From 1 to 3 :
Path: 1-->2-->3
Total cost : 6
*/