http://acm.hdu.edu.cn/showproblem.php?pid=1385
题意:求起点到终点的最短路,注意点是有权值的。然后要按找字典序输出路径。
分析:说实话这题卡了我好久,从数据没过到坑坑爹爹的把数据过了,再到改啊改一直wa,我已经很满足了因为我耐住了性子,其实我一点也不希望他ac,要不然太没劲了。好吧这题wa了我18次。关键的地方就是按照字典序输出,由于我以前是按照另外一种方法存储路径导致一直wa。现在换一种方法。
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end const int infmax = 100000000; const int maxn = 510; int n,m; int edge[maxn][maxn]; int dis[maxn][maxn]; int path[maxn][maxn]; int nodeedge[maxn]; void floyd(){ int len; for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ len=dis[i][k]+dis[k][j]+nodeedge[k]; if(dis[i][j]>len){ dis[i][j]=len; path[i][j]=path[i][k]; } else if(len==dis[i][j]){ if(path[i][j]>path[i][k]){ path[i][j]=path[i][k]; } } } } } } int main(){ while(scanf("%d",&n)!=EOF){ if(n==0) break; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ dis[i][j]=infmax; } dis[i][i]=0; } int w; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&w); if(w!=-1){ dis[i][j]=w; } } } for(int i=1;i<=n;i++){ scanf("%d",&nodeedge[i]); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ path[i][j]=j; } } floyd(); int start,end; while(scanf("%d%d",&start,&end)!=EOF){ if(start==-1&&end==-1) break; if(dis[start][end]==infmax){ printf("-1\n"); continue; } if(start==end){ printf("From %d to %d :\n",start,end); printf("Path: %d\n",start); printf("Total cost : 0\n\n"); continue; } printf("From %d to %d :\n",start,end); printf("Path: %d",start); int k=start; while(k!=end){ printf("-->%d",path[k][end]); k=path[k][end]; } printf("\n"); printf("Total cost : %d\n\n",dis[start][end]); } } return 0; }
以前的存储路径是保存在shortest[]中的,可以借鉴一下,我觉得还是很好的,以后还是用上面代码中的path[][]...我wa怕了。。呵呵
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end const int infmax = 100000000; const int maxn = 510; int n,m; int edge[maxn][maxn]; int dis[maxn][maxn]; int path[maxn][maxn]; int nodeedge[maxn]; void floyd(){ int len; for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ if(i==k||dis[i][k]==INF) continue; for(int j=1;j<=n;j++){ if(i==k||k==j||dis[k][j]==INF) continue; len=dis[i][k]+dis[k][j]+nodeedge[k]; if(dis[i][j]>len||dis[i][j]==INF){ dis[i][j]=dis[i][k]+dis[k][j]+nodeedge[k]; path[i][j]=path[k][j]; } else if(len==dis[i][j]&&path[k][j]<path[i][j]){ // if(path[i][j]>path[k][j]){ path[i][j]=path[k][j]; //} } // printf("dis[i][j]=%d\n",dis[i][j]); } } } } int main(){ while(scanf("%d",&n)!=EOF){ //³õʼ»¯ if(n==0) break; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ dis[i][j]=infmax; //if(i!=j&&dis[i][j]<INF) path[i][j]=i; //else path[i][j]=-1; } dis[i][i]=0; } int w; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&w); if(w==-1){ dis[i][j]=infmax; } else dis[i][j]=w; } } // for(int i=1;i<=n;i++){ // for(int j=1;j<=n;j++){ // printf("%d ",dis[i][j]); // } // printf("\n"); // } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j&&dis[i][j]!=infmax) path[i][j]=i; else path[i][j]=-1; } } for(int i=1;i<=n;i++){ scanf("%d",&nodeedge[i]); } floyd(); int start,end; int shortest[maxn]; while(scanf("%d%d",&start,&end)!=EOF){ if(start==-1&&end==-1) break; if(dis[start][end]==infmax){ printf("-1\n"); continue; } if(start==end){ printf("From %d to %d :\n",start,end); printf("Path: %d\n",start); printf("Total cost : 0\n\n"); continue; } printf("From %d to %d :\n",start,end); memset(shortest,0,sizeof(shortest)); int k=0; shortest[k]=end; while(path[start][shortest[k]]!=start){ k++; shortest[k]=path[start][shortest[k-1]]; } k++; shortest[k]=start; printf("Path: "); for(int j=k;j>0;j--){ printf("%d-->",shortest[j]); } printf("%d\n",shortest[0]); printf("Total cost : %d\n\n",dis[start][end]); } } return 0; }