Minimum Transport Cost
题目链接
These are N cities in Spring country. Between each pair of cities there may be one transportation track or none. Now there is some cargo that should be delivered from one city to another. The transportation fee consists of two parts:
The cost of the transportation on the path between these cities, and
a certain tax which will be charged whenever any cargo passing through one city, except for the source and the destination cities.
You must write a program to find the route which has the minimum cost.
Input
First is N, number of cities. N = 0 indicates the end of input.
The data of path cost, city tax, source and destination cities are given in the input, which is of the form:
a11 a12 … a1N
a21 a22 … a2N
…
aN1 aN2 … aNN
b1 b2 … bN
c d
e f
…
g h
where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, …, and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:
Output
From c to d :
Path: c–>c1–>…–>ck–>d
Total cost : …
…
From e to f :
Path: e–>e1–>…–>ek–>f
Total cost : …
Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
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
题目大意
现在有一个n*n的矩阵,每个点代表第i行的点到达这一列的距离
自身距离为0,如果是-1的话就是无法到达,不是0和-1的话就是到达需要的路费
还有就是到达每个地点需要收税
n行下有m个元素代表经过这个城市所要的税
起点和终点是不需要交税的
之后有多组数据,每组数据为查询两点间需要通过的最小费用路径和总费用
当输入-1 -1的时候表示结束
注意:如果存在更多最小路径,则输出上最小的路径。在每个测试用例之后打印空白行。
算法分析
税的方面加和到路费上就行,这道题我们选用Floyd来进行操作,Floyd在记录路径方面要比其他算法要方便;我们用一个二维数组来记录行走路径 然后看代码理解吧
代码实现
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
const int maxn=105;
int dis[maxn][maxn]; //dis[i][j]表示i到j的距离;
int path[maxn][maxn]; //path[i][j]代表从i到j需要到达的第一个位置
int shui[maxn]; //收税费用
int n;
void init() //初始化
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j)
dis[i][j]=0x3f; //先初始化为无穷大
else
dis[i][j]=0; //自身距离为0
path[i][j]=j;
}
}
}
void Floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(dis[i][k]!=0x3f&&dis[k][j]!=0x3f)
{
int diss=dis[i][k]+dis[k][j]+shui[k];
if(dis[i][j]>diss)
{
dis[i][j]=diss;
path[i][j]=path[i][k]; //到达第一个点的转移
}
else if(dis[i][j]==diss&&path[i][j]>path[i][k])//相同费用下,谁小去谁那
{
path[i][j]=path[i][k];
}
}
}
}
int main()
{
int m;
while(cin>>n&&n)
{
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&dis[i][j]);
if(dis[i][j]==-1)
dis[i][j]=0x3f;
}
}
for(int i=1;i<=n;i++)
scanf("%d",&shui[i]);
Floyd();
int st,fin;
while(cin>>st>>fin)
{
if(st==-1&&fin==-1)
break;
printf("From %d to %d :\n",st,fin);
printf("Path: %d",st);
int u=st;
while(u!=fin)
{
printf("-->%d",path[u][fin]);
u=path[u][fin];
}
cout<<endl;
printf("Total cost : %d\n\n",dis[st][fin]);
}
}
}