题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392
这题挺经典的,可以用来熟悉Dijkstra算法

代码

纯Dijkstra算法

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<vector>
  5. using namespace std;
  6. const int maxn = 510;
  7. const int inf = 0x3fffffff;
  8. int n, m, st, ed;
  9. int G[maxn][maxn], cost[maxn][maxn], pre[maxn], d[maxn], c[maxn];
  10. bool vis[maxn] = {false};
  11. void Dijkstra(int s){
  12. fill(d, d + maxn, inf);
  13. fill(c, c + maxn, inf);
  14. d[s] = 0;
  15. c[s] = 0;
  16. for(int i = 0; i < n; i++) pre[i] = i;
  17. for(int i = 0 ; i < n; i++){
  18. int u = -1, min = inf;
  19. for(int j = 0; j < n; j++){
  20. if(vis[j] == false && d[j] < min){
  21. u = j;
  22. min = d[j];
  23. }
  24. }
  25. if(u == -1) return;
  26. vis[u] = true;
  27. for(int v = 0; v < n; v++){
  28. if(vis[v] == false && G[u][v] != inf){
  29. if(G[u][v] + d[u] < d[v]){
  30. d[v] = G[u][v] + d[u];
  31. c[v] = cost[u][v] + c[u];
  32. pre[v] = u;
  33. } else if(d[v] == G[u][v] + d[u]){
  34. if(c[v] > cost[u][v] + c[u]){
  35. c[v] = cost[u][v] + c[u];
  36. pre[v] = u;
  37. }
  38. }
  39. }
  40. }
  41. }
  42. }
  43. void DFS(int v){
  44. if(v == st){
  45. printf("%d ", v);
  46. return;
  47. }
  48. DFS(pre[v]);
  49. printf("%d ",v);
  50. }
  51. int main(){
  52. scanf("%d%d%d%d", &n, &m, &st, &ed);
  53. int c1, c2, temp_d, temp_c;
  54. fill(G[0], G[0] + maxn * maxn, inf);
  55. for(int i = 0; i < m; i++){
  56. scanf("%d%d%d%d", &c1, &c2, &temp_d, &temp_c);
  57. G[c1][c2] = G[c2][c1] = temp_d;
  58. cost[c1][c2] = cost[c2][c1] = temp_c;
  59. }
  60. Dijkstra(st);
  61. DFS(ed);
  62. printf("%d %d\n", d[ed], c[ed]);
  63. return 0;
  64. }

Dijkstra + DFS

感觉用不太上,熟悉第一种写法就够了.jpg 注意DFS函数的写法!!!

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<vector>
  4. #include<algorithm>
  5. using namespace std;
  6. const int maxn = 510;
  7. const int inf = 1000000000;
  8. int n, m, st, ed, G[maxn][maxn], cost[maxn][maxn];
  9. int d[maxn], minCost = inf;
  10. bool vis[maxn] = {false};
  11. vector<int> pre[maxn];
  12. vector<int> tempPath, path;
  13. void Dijkstra(int s){
  14. fill(d, d + maxn, inf);
  15. d[s] = 0;
  16. for(int i = 0 ; i < n; i++){
  17. int u = -1, min = inf;
  18. for(int j = 0; j < n; j++){
  19. if(vis[j] == false && d[j] < min){
  20. u = j;
  21. min = d[j];
  22. }
  23. }
  24. if(u == -1)return;
  25. vis[u] = true;
  26. for(int v = 0; v < n; v++){
  27. if(vis[v] == false && G[u][v] != inf){
  28. if(d[v] > d[u] + G[u][v]){
  29. d[v] = d[u] + G[u][v];
  30. pre[v].clear();
  31. pre[v].push_back(u);
  32. } else if(d[v] == d[u] + G[u][v]){
  33. pre[v].push_back(u);
  34. }
  35. }
  36. }
  37. }
  38. }
  39. void DFS(int v){
  40. if(v == st){
  41. tempPath.push_back(v);
  42. int tempCost = 0;
  43. for(int i = tempPath.size() - 1; i > 0; i--){
  44. int id = tempPath[i], idNext = tempPath[i - 1];
  45. tempCost += cost[id][idNext];
  46. }
  47. if(tempCost < minCost){
  48. minCost = tempCost;
  49. path = tempPath;
  50. }
  51. tempPath.pop_back();
  52. return;
  53. }
  54. tempPath.push_back(v);
  55. for(int i = 0; i < pre[v].size(); i++){
  56. DFS(pre[v][i]);
  57. }
  58. tempPath.pop_back();
  59. }
  60. int main(){
  61. scanf("%d%d%d%d", &n, &m, &st, &ed);
  62. int c1, c2, temp_d, temp_c;
  63. fill(G[0], G[0] + maxn * maxn, inf);
  64. for(int i = 0; i < m; i++){
  65. scanf("%d%d%d%d", &c1, &c2, &temp_d, &temp_c);
  66. G[c1][c2] = G[c2][c1] = temp_d;
  67. cost[c1][c2] = cost[c2][c1] = temp_c;
  68. }
  69. Dijkstra(st);
  70. DFS(ed);
  71. for(int i = path.size() - 1; i >= 0; i--){
  72. printf("%d ", path[i]);
  73. }
  74. printf("%d %d\n", d[ed], minCost);
  75. return 0;
  76. }