J. Walk This Way

5 篇文章 0 订阅
  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,tOutput 
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. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值