Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4503 Accepted Submission(s): 1121
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 }