[关闭]
@zimenglan 2014-11-29T09:13:19.000000Z 字数 4040 阅读 1429
  1. J. Walk This Way

最短路径


题目

Description
Rocking is a fat boy, and he does not like walking at all. Whenever he goes somewhere, he always tries to find a bus to take. But he lives in a city where he can not go everywhere by bus. So, he wants you to help him find the best way to his destination, which has the shortest distance for him to walk.
Remember the places in the city are numbered from 0 to N-1.
Input
Input consists of T cases, with T in the first line.
In each case, the first line contains two integers, N(2<=N<=100),the number of the places in Rocking's city, and M(0<=M<=N*(N-1)/2), the number of the roads.
The next M lines each contains four integers: a,b,c,d(0<=a,b The last line contains two integers s,t(0<=s,t Output
For each case, output a integer in a single line, indicating the shortest distance he must walk. Note that Rocking can take as many buses as he wants, and he only focus on the roads he must walk on.
If he can not get to his destination, please output -1.


大概意思就是能take busedgeweight为0, 然后找出一条最短路径的cost.


Code

下面给出Dijkstra和Floyd的代码

Dijkstra

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <list>
  4. #include <map>
  5. #include <vector>
  6. #include <string>
  7. #include <cstring>
  8. #include <string.h>
  9. using namespace std;
  10. const int N = 102;
  11. const int M = N * N;
  12. const int INF = 100000;
  13. bool visit[N];
  14. int edge[N][N];
  15. int dist[N];
  16. int parent[N];
  17. // m: number of edge
  18. // n: number of vertices
  19. void init(const int m, const int n) {
  20. // memset(edge, INF, sizeof(edge));
  21. // memset(edge, INF, M * sizeof(int));
  22. for(int i = 0; i < n; i++) {
  23. for(int j = 0; j < n; j++) {
  24. if(i == j) {
  25. edge[i][j] = 0;
  26. continue;
  27. }
  28. edge[i][j] = INF;
  29. }
  30. }
  31. int u, v, c, flag;
  32. for(int i = 0; i < m; i++) {
  33. cin >> u >> v >> c >> flag;
  34. edge[u][v] = flag != 0 ? 0 : c;
  35. edge[v][u] = edge[u][v];
  36. }
  37. }
  38. // m: number of edge
  39. // n: number of vertices
  40. // s: index of start place
  41. // e: index destination
  42. void dijkstra(const int m, const int n, const int s,
  43. const int e, const bool isPath = false)
  44. {
  45. for(int i = 0; i < n; i++) {
  46. dist[i] = i == s ? 0 : INF;
  47. parent[i] = -1;
  48. }
  49. //
  50. memset(visit, false, sizeof(visit));
  51. /*
  52. n iteration because there are n vertices
  53. each iteration t, select the t th vertex whose cost is t th smallest,
  54. then refresh the weights beteen it and other vertices
  55. */
  56. for(int i = 0; i < n; i++) {
  57. int u = -1, c = INF;
  58. for(int j = 0; j < n; j++) {
  59. if(!visit[j] && dist[j] <= c) {
  60. u = j;
  61. c = dist[j];
  62. }
  63. }
  64. if(u == -1) {
  65. continue;
  66. // exit(1);
  67. }
  68. visit[u] = true;
  69. // relax, at the same time, record the path
  70. for(int v = 0; v < n; v++) {
  71. if(dist[v] > dist[u] + edge[u][v]) {
  72. dist[v] = dist[u] + edge[u][v];
  73. parent[v] = u;
  74. }
  75. }
  76. }
  77. if(dist[e] < INF) {
  78. std::cout << dist[e] << endl;
  79. }
  80. if(isPath) {
  81. int v = e;
  82. std::cout << "end <- ";
  83. while(parent[v] != -1) {
  84. std::cout << v << " <- ";
  85. v = parent[v];
  86. }
  87. std::cout << v << " <- start" << std::endl;
  88. }
  89. }
  90. int main() {
  91. /*
  92. test case:
  93. 1
  94. 5 6
  95. 0 1 10 1
  96. 1 2 20 1
  97. 2 4 2 0
  98. 0 3 1 0
  99. 3 4 2 0
  100. 0 2 40 1
  101. 0 4
  102. ans: 2
  103. */
  104. int T;
  105. cin >> T;
  106. while(T--) {
  107. int m, n;
  108. int s, e;
  109. // get the numbers of vertices and edges
  110. cin >> n >> m;
  111. // inti the edges or weights and something else
  112. init(m, n);
  113. // get start place and destination
  114. cin >> s >> e;
  115. bool isPath = true;
  116. // find the shortest path and its corresponding cost
  117. dijkstra(m, n, s, e, isPath);
  118. }
  119. }

Floyd

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <list>
  4. #include <map>
  5. #include <vector>
  6. #include <string>
  7. #include <cstring>
  8. #include <string.h>
  9. using namespace std;
  10. const int N = 102;
  11. const int M = N * N;
  12. const int INF = 100000;
  13. bool visit[N];
  14. int edge[N][N];
  15. // m: number of edge
  16. // n: number of vertices
  17. void init(const int m, const int n) {
  18. // memset(edge, INF, sizeof(edge));
  19. // memset(edge, INF, M * sizeof(int));
  20. for(int i = 0; i < n; i++) {
  21. for(int j = 0; j < n; j++) {
  22. if(i == j) {
  23. edge[i][j] = 0;
  24. continue;
  25. }
  26. edge[i][j] = INF;
  27. }
  28. }
  29. memset(visit, false, sizeof(visit));
  30. int u, v, c, flag;
  31. for(int i = 0; i < m; i++) {
  32. cin >> u >> v >> c >> flag;
  33. edge[u][v] = flag ? 0 : c;
  34. edge[v][u] = edge[u][v];
  35. }
  36. }
  37. // m: number of edge
  38. // n: number of vertices
  39. void Floyd(const int m, const int n) {
  40. for(int k = 0; k < n; k++) {
  41. for(int i = 0; i < n; i++) {
  42. for(int j = 0; j < n; j++) {
  43. // if(edge[i][j] < INF && edge[i][k] < INF && edge[k][j] < INF) {
  44. // error
  45. // if(edge[i][j] <= INF && edge[i][k] <= INF && edge[k][j] <= INF) {
  46. // right, but no meaning
  47. // if(edge[i][j] < INF && edge[k][j] < INF) {
  48. // error
  49. if(edge[i][j] < INF && edge[k][j] < INF) {
  50. // right
  51. if(edge[i][j] > edge[i][k] + edge[k][j]) {
  52. edge[i][j] = edge[i][k] + edge[k][j];
  53. edge[j][i] = edge[i][j];
  54. }
  55. }
  56. }
  57. }
  58. }
  59. }
  60. int main() {
  61. /*
  62. test case:
  63. 1
  64. 5 6
  65. 0 1 10 1
  66. 1 2 20 1
  67. 2 4 2 0
  68. 0 3 1 0
  69. 3 4 2 0
  70. 0 2 40 1
  71. 0 4
  72. ans: 2
  73. */
  74. int T;
  75. cin >> T;
  76. while(T--) {
  77. int m, n;
  78. int s, e;
  79. // get the numbers of vertices and edges
  80. cin >> n >> m;
  81. // inti the edges or weights and something else
  82. init(m, n);
  83. // get start place and destination
  84. cin >> s >> e;
  85. std::cout << "s: " << s << ", e: " << e << std::endl;
  86. // find the shortest path and its corresponding cost
  87. Floyd(m, n);
  88. int cost = edge[s][e];
  89. if(cost < INF) {
  90. std::cout << cost << std::endl;
  91. } else {
  92. std::cout << "failed: ";
  93. std::cout << -1 << std::endl;
  94. }
  95. }
  96. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注