最短路径 -- spfa
2015-09-29 11:53
726 查看
最短路径 – spfa
Google的第二轮,第一题就是一道图论题目,对于图论薄弱的我,简直是当头一棒!看题戳这里
此题略复杂,不过看过大牛的解题报告之后,深感自己弱爆了。
大牛的解题报告戳这里
此题还是单源最短路问题,只是分成了24小时的动态路径,而由于题目中的限制条件:
It is guaranteed that
Cost[t] ≤ Cost[t+1]+1 (0 ≤ t ≤ 22) and Cost[23] ≤ Cost[0]+1.
使得我们熟知的最短路算法可以得到正确的解(详细解释参看大牛的报告)
借此机会,学习了一下 spfa 算法
参考资料戳这里
感谢以上引用的各位博主!
附上通过代码(C++)
#include <stdio.h> #include <limits.h> #include <string.h> #include <queue> #define IMAX (INT_MAX/2) #define min(a,b) (((a) < (b)) ? (a) : (b)) using namespace std; int T, Ti, N, M, K, D, S, x, y, t, i, j; int cost[501][501][24], dis[501][24], vis[501]; //cost 记录输入路径 //dis 以0~23小时开始的单源最短路的距离 //vis spfa算法的中间变量,记录访问状态 //初始化数组 void init() { for (i = 0; i <= N; i++) { for (j = 0; j <= N; j++) { for (t = 0; t < 24; t++) { cost[i][j][t] = IMAX; } } } for (i = 0; i <= N; i++) { for (t = 0; t < 24; t++) { cost[i][i][t] = 0; } } memset(dis, 0, sizeof(dis)); for (i = 2; i <= N; i++) { for (t = 0; t < 24; t++) { dis[i][t] = IMAX; } } } int main() { scanf("%d", &T); for (Ti = 1; Ti <= T; Ti++) { scanf("%d %d %d", &N, &M, &K); init(); //处理输入 for (i = 0; i < M; i++) { scanf("%d %d", &x, &y); for (j = 0; j < 24; j++) { scanf("%d", &t); cost[x][y][j] = min(cost[x][y][j], t); cost[y][x][j] = min(cost[y][x][j], t); } } //对24小时的每个小时做一遍 for (t = 0; t < 24; t++) { // spfa算法 queue<int> que; que.push(1); memset(vis, 0, sizeof(vis)); vis[1] = 1; while (!que.empty()) { int pre = que.front(); for (i = 1; i <= N; i++) { if (cost[pre][i][0] == IMAX) continue; int tm = (t + dis[pre][t]) % 24; //计算时间差,适应动态路径的权重 if (dis[i][t] > dis[pre][t] + cost[pre][i][tm]) { dis[i][t] = dis[pre][t] + cost[pre][i][tm]; if (vis[i] == 0) { vis[i] = 1; que.push(i); } } } que.pop(); vis[pre] = 0; } } //O(1)时间查找输出 printf("Case #%d:", Ti); for (i = 0; i < K; i++) { scanf("%d %d", &D, &S); if (dis[D][S] == IMAX) { printf(" -1"); } else { printf(" %d", dis[D][S]); } } printf("\n"); } return 0; }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例