Dijkstra算法求最短路和比最短路长1的路径的数目(单源最短路径plus)
2017-03-28 23:34
453 查看
题目描述
人类和人鱼拥有共同的祖先,因为某种原因发生了分化,人鱼到了大海里生活。近年来人类对大海及生态的破坏,人鱼族的生存环境受到了严重的影响。最近某地产公司筹备一个填海计划,在附近的大海中装入了声呐系统,这极大地限制了人鱼的活动。人鱼族的居民们为了适应环境,建立了n个聚居点(从1到n编号),m条有一定长度的单向通道,每条由一个聚居点通向另一个聚居点。人鱼族派出了美人鱼珊珊去勾引地产公司的老总刘轩,来逼迫他关闭声呐系统。现在珊珊在S号点,她要到T号点,然后通过T号点到达陆地上。她当然希望自己能走最短的路来从S到达T,不过比最短路长1的路径,她也是可以接受的。她想知道从S到T的最短路和比最短路长1的路径一共有多少条。
输入
输入数据共m+2行。第一行两个数n,m,含义如题目所述。(1<=n<=1000,1<=m<=15000)
第2到m+1行,共m行,每行3个数a[i],b[i],c[i],表示从a[i]到b[i]有一条长度为c[i]的通道(1<=a[i],b[i]<=n,1<=c[i]<=10000,可能有重边)。
第m+2行两个数S,T,含义如题目所述。
输出
输出一个数,表示从S到T的最短路和比最短路长1的路径的数目。#include<iostream> #define max 10001 using namespace std; struct edg { int w; int to; int next; }; class G { private: edg *edgs; int dis[50][2][2]; int n, m, S, T, num; bool isar[50][2]; void path() { int l, i, j, v, min, k, len; dis[S][0][0] = 0; for (l = 0; l < 2 * n; l++) { v = -1; min = max; for (j = 0; j < n; j++) { if (!isar[j][0] && dis[j][0][0] < min) { min = dis[j][0][0]; v = j; k = 0; } else if (!isar[j][1] && dis[j][1][0] < min) { min = dis[j][1][0]; v = j; k = 1; } } if (v == -1) break; isar[v][k] = true; for (j = v; edgs[j].next != -1; j = edgs[j].next) { len = edgs[j].w; i = edgs[j].to; len = len + dis[v][k][0]; if (len < dis[i][0][0]) { dis[i][1][0] = dis[i][0][0]; dis[i][1][1] = dis[i][0][1]; dis[i][0][0] = len; dis[i][0][1] = dis[v][k][1]; } else if (len == dis[i][0][0]) { dis[i][0][1] += dis[v][k][1]; } else if (len < dis[i][1][0]) { dis[i][1][0] = len; dis[i][1][1] = dis[v][k][1]; } else if (len == dis[i][1][0]) { dis[i][1][1] += dis[v][k][1]; } } } } public: G(int m, int n) { int i, j, x, y, l; num = n; this->m = m; this->n = n; edgs = new edg[m + n]; for (i = 0; i < n; i++) { edgs[i].next = -1; } for (i = 0; i < m; i++) { cin >> x >> y >> l; x--, y--; j = x; while (edgs[j].next != -1) { j = edgs[j].next; } edgs[j].to = y; edgs[j].w = l; edgs[j].next = num; edgs[num++].next = -1; dis[i][0][0] = dis[i][1][0] = max; dis[i][0][1] = dis[i][1][1] = 1; isar[i][0] = isar[i][1] = false; } cin >> S >> T; S--, T--; } void ans() { path(); if (dis[T][0][0] + 1 == dis[T][1][0]) { cout << dis[T][0][1] + dis[T][1][1] << endl; } else cout << dis[T][0][1] << endl; } }; int main() { int m, n; while (cin >> n >> m) { G *g = new G(m, n); (*g).ans(); delete g; } return 0; }
相关文章推荐
- HDU 3790 最短路径问题(单源最短路---Dijkstra算法)
- 最小生成树Prim算法和单源最短路径Dijkstra算法
- 越獄之权值非负单源最短路径问题-Dijkstra算法
- 单源最短路径问题之dijkstra算法
- (转)图算法单源最短路径Dijkstra算法(邻接表/邻接矩阵+优先队列STL)
- HDU 3790 最短路径问题(单源最短路)
- 算法导论学习笔记(18)——单源最短路径(Dijkstra算法实现)
- [HDU](2544)最短路 ---单源最短路径(图)
- Dijkstra算法——单源最短路径问题
- Dijkstra算法(单源最短路径)C#版
- HDU:最短路(单源最短路径Dijistra)
- Dijkstra算法(单源最短路径) C++
- Dijkstra算法(单源最短路径)
- 单源最短路径--Dijkstra算法
- Dijkstra算法(单源最短路径)
- 算法导论-单源最短路径-Dijkstra算法的实现
- Dijkstra算法--单源最短路径
- Dijkstra算法(求单源最短路径)
- 单源最短路径 dijkstra算法实现
- 单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))