Minimum Transport Cost
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4503 Accepted Submission(s): 1121
Problem Description
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.
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:
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.
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
1 /* 2 //代码一(dijkstra未提交)---题目中要求路径按照字典序最小,这个条件还没想到方法满足 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #define inf 0x3fffffff 7 int **map,*tax; 8 9 void dijks(int s,int t,int n) 10 { 11 bool *visit=new bool[n+1]; 12 int *dis=new int[n+1]; 13 int *path=new int[n+1]; 14 int i,j,k,min,count; 15 count=1; 16 memset(visit,false,(n+1)*sizeof(bool)); 17 visit[s]=true; 18 path[count++]=s; 19 for(i=1;i<=n;++i) 20 dis[i]=map[s][i]+tax[i]; 21 dis[t]-=tax[t]; 22 dis[s]-=tax[s]; 23 for(i=1;i<n;++i) 24 { 25 min=inf; 26 k=1; 27 for(j=1;j<=n;++j) 28 { 29 if(!visit[j]&&min>dis[j]) 30 { 31 min=dis[j]; 32 k=j; 33 } 34 } 35 visit[k]=true; 36 if(k==t) 37 break; 38 path[count++]=k; 39 for(j=1;j<=n;++j) 40 { 41 if(!visit[j]) 42 { 43 if(j!=t&&dis[k]+map[k][j]+tax[j]<dis[j]) 44 dis[j]=dis[k]+map[k][j]+tax[j]; 45 if(j==t&&dis[k]+map[k][j]<dis[j]) 46 dis[j]=dis[k]+map[k][j]; 47 } 48 } 49 } 50 for(i=1;i<count;++i) 51 printf("%d-->",path[i]); 52 printf("%d\nTotal cost : %d\n\n",t,dis[t]); 53 } 54 55 int main() 56 { 57 int n,i,j,a,b; 58 while(scanf("%d",&n),n) 59 { 60 map=new int*[n+1]; 61 tax=new int[n+1]; 62 for(i=0;i<=n;++i) 63 map[i]=new int[n+1]; 64 for(i=1;i<=n;++i) 65 for(j=1;j<=n;++j) 66 { 67 scanf("%d",&map[i][j]); 68 if(map[i][j]==-1) 69 map[i][j]=inf; 70 } 71 for(i=1;i<=n;++i) 72 scanf("%d",&tax[i]); 73 while(scanf("%d%d",&a,&b),a!=-1||b!=-1) 74 { 75 printf("From %d to %d :\nPath: ",a,b); 76 if(a==b) 77 { 78 printf("%d\nTotal cost : 0\n\n",a); 79 continue; 80 } 81 dijks(a,b,n); 82 } 83 } 84 return 0; 85 } 86 */ 87 88 //代码二:(floyd并记录路径) 89 /* 90 参考网上思路: 91 典型的floyd,这里使用path数组来记录路径,path[a][b]表示a到b的所有路径中的与a最近的一个结点, 92 path[a][a]则记录当前结点a。另外题目要求按字典序输出结果,只要判断当路径权值相同时,更新结点值小的那个路径即可! 93 */ 94 95 #include<cstdio> 96 #include<cstdlib> 97 #include<cstring> 98 #define inf 0x3ffffff 99 int **map,*tax,**path; 100 101 void floyd(int n) 102 { 103 int i,j,k; 104 for(k=1;k<=n;++k) 105 for(i=1;i<=n;++i) 106 for(j=1;j<=n;++j) 107 { 108 int tmp=map[i][k]+map[k][j]+tax[k]; //把每个城市的过路费加在这里计算出来的正好是不加首位城市过路费的总费用 109 if(map[i][j]>tmp) // 小郁闷~~---其实也可以换成我上边的dijkstra的数据处理方式,除去首位节点外, 110 { //其他节点的距离都加上tax存到map中 111 map[i][j]=tmp; 112 path[i][j]=path[i][k]; // 记录当前路径 113 } 114 else if(map[i][j]==tmp) //最短路有多条,选取字典序最小的 115 { 116 if(path[i][j]>path[i][k]) 117 path[i][j]=path[i][k]; 118 } 119 } 120 } 121 122 int main() 123 { 124 int n,i,j,a,b,t; 125 while(scanf("%d",&n),n) 126 { 127 map=new int*[n+1]; 128 path=new int*[n+1]; 129 tax=new int[n+1]; 130 for(i=0;i<=n;++i) 131 { 132 map[i]=new int[n+1]; 133 path[i]=new int[n+1]; 134 } 135 for(i=1;i<=n;++i) 136 for(j=1;j<=n;++j) 137 { 138 path[i][j]=j; //(路径记录)----很神奇 139 scanf("%d",&map[i][j]); 140 if(map[i][j]==-1) 141 map[i][j]=inf; 142 } 143 for(i=1;i<=n;++i) 144 scanf("%d",&tax[i]); 145 floyd(n); 146 while(scanf("%d%d",&a,&b),a!=-1||b!=-1) 147 { 148 printf("From %d to %d :\nPath: %d",a,b,a); 149 t=a; 150 while(t!=b) 151 { 152 printf("-->%d",path[t][b]); 153 t=path[t][b]; 154 } 155 printf("\nTotal cost : %d\n\n",map[a][b]); 156 } 157 } 158 return 0; 159 }