HDOJ-1385 Minimum Transport Cost -----路径记录floyd

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.
 

 

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
 
  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 }

 

你可能感兴趣的:(floyd)