这些是春天乡村的N个城市。每对城市之间可能有一条或没有交通轨道。现在有一些货物需要从一个城市运到另一个城市。运输费用由两部分组成:这些城市之间道路上的交通费。任何货物经过一个城市都要缴纳一定的税,但来源地和目的地城市除外。
你必须编写一个程序来找出成本最低的路线。
输入
首先是N个城市。N = 0表示输入结束。输入路径成本、城市税费、来源地、目的地城市数据,形式为:a11 a12…a1N a21 a22…a2N …aN1 aN2……aNN b1 b2…bN cd e f…g h aij哪里运输成本从城市我j,aij = 1表示我和城市之间没有直接的路径j . val[i]代表我穿过城市的税收。交付货物从城市c d,f e城市,…, g = h = -1。您必须输出经过的城市序列和总成本,其形式如下:
输出
从c到d:路径:c——>c1——>——>ck——>d总成本:
从e到f:路径:e——>e1——>——>ek——>f总成本:
注意:如果有更多的最小路径,则输出词法上最小的路径。在每个测试用例之后打印一个空白行。
Sample Input
5
0 3 22 -1 4
3 0 5 -1 -1
22 5 0 9 20
-1 -1 9 0 4
4 -1 20 4 0
5 17 8 3 1
1 3
3 5
2 4
-1 -1
0
Sample Output
From 1 to 3 :
Path: 1–>5–>4–>3
Total cost : 21
From 3 to 5 :
Path: 3–>4–>5
Total cost : 16
From 2 to 4 :
Path: 2–>1–>5–>4
Total cost : 17
path[i][j]表示 从 i 到 j 第一个经过的点 当然 i 不算
剩下的过程就和带权最短路是一样的 满足最短路的情况的同时来满足其他的条件。
#include <cstdio>
using namespace std;
const int N=205;
const int INF=0x3f3f3f3f;
int e[N][N],path[N][N],val[N];
int n;
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
if(e[i][k]==INF)
continue;
for(int j=1;j<=n;j++)
{
if(e[k][j]==INF)
continue;
int tmp=e[i][k]+e[k][j]+val[k];
if(e[i][j]>tmp)
{
e[i][j]=tmp;
path[i][j]=path[i][k];
}
else if(e[i][j]==tmp&&path[i][j]>path[i][k])
{
path[i][j]=path[i][k];
}
}
}
}
}
void print(int s,int t)
{
printf("From %d to %d :\n",s,t);
printf("Path: %d",s);
int x=s;
while(x!=t)
{
printf("-->%d",path[x][t]);
x=path[x][t];
}
printf("\nTotal cost : %d\n",e[s][t]);
}
int main()
{
while(~scanf("%d",&n),n)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&e[i][j]);
if(e[i][j]==-1)
e[i][j]=INF;
path[i][j]=j;
}
for(int i=1;i<=n;i++)
{
e[i][i]=0;
scanf("%d",&val[i]);
}
floyd();
int s,t;
while(~scanf("%d%d",&s,&t),s!=-1||t!=-1)
{
print(s,t);
puts("");
}
}
}