[关闭]
@Moritz 2019-03-29T08:20:32.000000Z 字数 2118 阅读 437

L2-001 紧急救援

unsolved PTA 最短路 C++ 所有文稿


紧急救援

关键词:unsolveddijkstra,邻接表,两次松弛

pre数组记录前一个城市,第二次对长度相同的路线进行城市救援军数量的松弛,path数组目前看来可有可无,直接用dis[s]替代即可。

案例只通过了一半,对照着网上参考的算法debug了老半天,除了顺序之外没有发现任何区别。

我的版本(为了和参考代码尽可能相同,改了很多)

  1. /*16:30-17:03*/
  2. /*18:30*/
  3. #include <iostream>
  4. #include <stack>
  5. #include <string.h>
  6. #include <algorithm>
  7. #include <stdio.h>
  8. using namespace std;
  9. const int maxn=510,MAX=0x3f3f3f;
  10. int n,m,s,d;
  11. int dis[maxn][maxn],a[maxn],vis[maxn],num[maxn];
  12. int path[maxn];//最短路值
  13. int maxx[maxn];//最短路径最大的权值和
  14. int pre[maxn];
  15. int main(){
  16. cin>>n>>m>>s>>d;
  17. memset(dis,MAX,sizeof(dis));
  18. memset(path,0,sizeof(path));
  19. memset(maxx,0,sizeof(maxx));
  20. memset(pre,0,sizeof(pre));
  21. memset(num,0,sizeof(num));
  22. memset(a,0,sizeof(a));
  23. memset(vis,0,sizeof(vis));
  24. for(int i=0;i<n;i++) {cin>>a[i];num[i]=1;}
  25. /*for(int i=0;i<maxn;i++){
  26. for(int j=0;j<maxn;j++){
  27. if (i==j) dis[i][j]=0;
  28. else dis[i][j]=MAX;
  29. }
  30. }*/
  31. for(int i=0;i<m;i++){
  32. int a,b,len;
  33. cin>>a>>b>>len;
  34. dis[a][b]=min(dis[a][b],len);//a到b的路
  35. dis[b][a]=min(dis[a][b],len);
  36. }
  37. for(int i=0;i<n;i++){
  38. if(i==s){
  39. path[i]=0;
  40. maxx[i]=a[i];
  41. }
  42. else{
  43. path[i]=dis[s][i];
  44. maxx[i]=a[s]+a[i];//划重点 这是干嘛?
  45. }
  46. if(i!=s&&dis[s][i]!=MAX)//与起点直接连接
  47. pre[i]=s;
  48. else pre[i]=-1;
  49. }
  50. vis[s]=1;
  51. for(int z=0;z<n;z++){
  52. int min=MAX,min_n;
  53. for(int i=0;i<n;i++){
  54. if (dis[s][i]<min&&!vis[i]){
  55. min=path[i];
  56. min_n=i;
  57. }
  58. }
  59. if(min==MAX){
  60. break; //不连通
  61. }
  62. vis[min_n]=1;
  63. //printf("insert min_n=%d\nset size=%d\n",min_n,found.size());
  64. /*
  65. for(int i=0;i<n;i++){
  66. if (!vis[i]){
  67. if (dis[s][i]>dis[min_n][i]+dis[s][min_n]){
  68. dis[s][i]=dis[min_n][i]+dis[s][min_n];
  69. maxx[i]=maxx[min_n]+a[i];
  70. pre[i]=min_n;
  71. num[i]=num[min_n];
  72. }
  73. else if(dis[s][i]==dis[min_n][i]+dis[s][min_n]){
  74. num[i]+=num[min_n];
  75. if (maxx[i]<maxx[min_n]+a[min_n]){
  76. maxx[i]=maxx[min_n]+a[i];
  77. pre[i]=min_n;
  78. }
  79. }
  80. }
  81. }*/
  82. int k=min_n;
  83. for(int j=0;j<n;j++){
  84. if(!vis[j]){
  85. if(path[j]>path[min_n]+dis[k][j]){
  86. path[j]=path[k]+dis[k][j];
  87. maxx[j]=maxx[k]+a[j];
  88. pre[j]=k;
  89. num[j]=num[k];
  90. }
  91. else if(path[j]==path[k]+dis[k][j]){
  92. num[j]=num[j]+num[k];
  93. if(maxx[j]<maxx[k]+a[j]){
  94. maxx[j]=maxx[k]+a[j];
  95. pre[j]=k;
  96. }
  97. //maxx[j]=max(maxx[j],maxx[k]+a[j]);
  98. }
  99. }
  100. }
  101. }
  102. cout<<num[d]<<" "<<maxx[d]<<endl;
  103. int sp=0;
  104. stack<int> st;
  105. for(int i=d;i!=-1;i=pre[i]) {st.push(i);}
  106. while(!st.empty()){
  107. if (sp++) cout<<" ";
  108. cout<<st.top();
  109. st.pop();
  110. }
  111. cout<<endl;
  112. system("pause");
  113. return 0;
  114. }

参考算法


2019.3.16

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注