首页 > 代码库 > 单源最短路径问题
单源最短路径问题
1 #define _CRT_SECURE_NO_WARNINGS 2 /* 3 7 10 4 0 1 5 5 0 2 2 6 1 2 4 7 1 3 2 8 2 3 6 9 2 4 1010 3 5 111 4 5 312 4 6 513 5 6 914 615 */16 #include <iostream>17 #include <vector>18 #include <algorithm>19 #include <cstdio>20 using namespace std;21 22 const int maxn = 1010 + 20;23 const int INF = 99999999;24 int cost[maxn][maxn]; //表示边e=(u,v)的权值 (不存在这条边时设为INF)25 int d[maxn]; //顶点出发的最短距离26 bool used[maxn]; //已经使用过的图27 int V, E;28 void init();29 void dijkstra(int s);30 void input();31 32 void init()33 {34 for (int i = 0; i < V; i++) {35 for (int j = 0; j < V; j++) {36 if (i == j) {37 cost[i][j] = 0;38 }39 else {40 cost[i][j] = INF;41 }42 }43 }44 }45 46 void dijkstra(int s)47 {48 fill(d, d + V, INF);49 fill(used, used + V, false);50 d[s] = 0;51 52 while (true) {53 int v = -1;54 //从尚未使用过的顶点中选择一个距离最小的顶点55 for (int u = 0; u < V; u++) {56 if (!used[u] && (v == -1 || d[u] < d[v])) {57 v = u;58 }59 }60 if (v == -1) break; //已经没有尚未使用的点了61 used[v] = true; //标志v已访问62 63 for (int u = 0; u < V; u++) {64 d[u] = min(d[u], d[v] + cost[u][v]);65 }66 }67 }68 69 void input()70 {71 int s, t, ct;72 for (int i = 0; i < E; i++)73 {74 cin >> s >> t >> ct;75 cost[s][t] = cost[t][s] = ct;76 }77 }78 79 int main()80 {81 cin >> V >> E; //输入顶点数和边数82 init(); //必须要初始化83 input(); //输入临接的边和权值84 dijkstra(0); //设置起点85 int ov;86 cin >> ov; //输入终点87 cout << d[ov] << endl;88 return 0;89 }
//解法二:
需要优化的是数值的插入(更新)和取出最小值两个操作,因此使用堆就可以了。把每个顶点当前的最短距离用堆维护,在更新最短距离时,把对应的元素往根的方向移动以满足堆的性质。而每次从堆中取出的最小值就是下一次要使用的顶点。这样堆中元素共有O(|V|)个。更新和取出数值的操作有O(|E|)次,因此整个算法复杂度是O(|E|log|V|)。
下面是使用STL的priority_queue的实现。在每次更新时往堆里插入当前最短距离和顶点的值对。插入的次数是O(|E|)次,因此元素也是O(|E|)个。当取的最小值不是最短距离的话,就丢弃这个值。
1 #define _CRT_SECURE_NO_WARNINGS 2 /* 3 7 10 4 0 1 5 5 0 2 2 6 1 2 4 7 1 3 2 8 2 3 6 9 2 4 1010 3 5 111 4 5 312 4 6 513 5 6 914 615 */16 #include <iostream>17 #include <vector>18 #include <utility>19 #include <queue>20 #include <functional>21 #include <algorithm>22 #include <cstdio>23 using namespace std;24 25 const int maxn = 1010 + 20;26 const int INF = 99999999;27 struct edge28 {29 int to, cost;30 };31 typedef pair<int, int> P; //first是最短距离,second是顶点的编号32 int V, E;33 vector<edge> G[maxn];34 int d[maxn];35 //void init();36 void input();37 38 void dijkstra(int s)39 {40 //通过指定greater<P>参数,堆按照first从小到大的顺序取出值41 priority_queue<P, vector<P>, greater<P> > que;42 fill(d, d + V, INF);43 d[s] = 0;44 que.push(P(0, s));45 46 while (!que.empty()) {47 P p = que.top(); que.pop();48 int v = p.second;49 if (d[v] < p.first) continue;50 for (int i = 0; i < G[v].size(); i++) {51 edge e = G[v][i];52 if (d[e.to] > d[v] + e.cost) {53 d[e.to] = d[v] + e.cost;54 que.push(P(d[e.to], e.to));55 }56 }57 }58 }59 60 //void init()61 //{ 62 //}63 64 void input()65 {66 int s, t, ct;67 edge tmp;68 for (int i = 0; i < E; i++) {69 cin >> s >> t >> ct;70 tmp.to = t; tmp.cost = ct;71 G[s].push_back(tmp);72 //无向图,反向也需要连接73 tmp.to = s; tmp.cost = ct;74 G[t].push_back(tmp);75 }76 }77 78 int main()79 {80 cin >> V >> E;81 //init();82 input();83 dijkstra(0);84 int ov;85 cin >> ov;86 cout << d[ov] << endl;87 return 0;88 }
单源最短路径问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。