C--最短路(Bellman-Ford或者SPFA)
2017-02-19 17:06
363 查看
think:
1题目由题意可知输入数据很大,而且顶点数达到了500000,如果用Dijkstra算法和Floyd算法定义的二维数组都无法达到500000*500000,因此可以考虑使用Bellma-Ford算法,不过得使用标记变量check用来标记数组dis在本轮松弛中是否发生了变化
2注意有权无向图
3题意提示权值大于等于0,如果权值存在小于零,适合用Belloc-Ford算法或Bellman-Ford算法的队列优化了
4反思:自己在t的变化上忽视了在每次循环中应使用两次t++,导致了有效数据被覆盖,数组一开始开小了,但自己感觉计算就应该是1<=n<=50000,1<=m<=200000,以后需要注意留心仔细一点
5尝试推测题意考察点,把握重点,注意细节
6刚才又学习了SPFA算法,用SPFA算法实现了一下,可能因为后台数据比较类型相似,两种算法实现的时间差不多,可能自己因为刚学习,一些SPFA算法的优化还不会,自己想同样加标记变量,结果可能加标记变量后一些位置重新松弛的时候变化不对,因此结果wrong answer,自己应该继续深入学习,争取学会SPFA算法很好的优化
7SPFA算法(Bellman-Ford算法的队列优化)
8Floyd算法的时间复杂度为O(N^3),Dijkstra算法的时间复杂度为O((M + N)logN),堆优化的Dijkstra算法时间复杂度可以达到O(MlogN),而Bellman-Ford算法的时间复杂度为O(NM),队列优化的Bellman-Ford算法时间复杂度最坏也是O(NM)
9Floyd算法和Dijkstra算法适合于稠密图,和顶点关系密切,而Bellman-Ford算法与队列优化的Bellman-Ford算法适合于稀疏图,和边关系密切
sdut原题链接
C–最短路
Time Limit: 7000MS Memory Limit: 65536KB
Problem Description
给出一个带权无向图,包含n个点,m条边。求出s,e的最短路。保证最短路存在。
Input
多组输入。
对于每组数据。
第一行输入n,m(1<= n && n<=5*10^5,1 <= m && m <= 2*10^6)。
接下来m行,每行三个整数,u,v,w,表示u,v之间有一条权值为w(w >= 0)的边。
最后输入s,e。
Output
对于每组数据输出一个整数代表答案。
Example Input
3 1
1 2 3
1 2
Example Output
3
Hint
Author
zmx
以下为accepted代码——Bellman-Ford
以下为accepted代码——SPFA算法
1题目由题意可知输入数据很大,而且顶点数达到了500000,如果用Dijkstra算法和Floyd算法定义的二维数组都无法达到500000*500000,因此可以考虑使用Bellma-Ford算法,不过得使用标记变量check用来标记数组dis在本轮松弛中是否发生了变化
2注意有权无向图
3题意提示权值大于等于0,如果权值存在小于零,适合用Belloc-Ford算法或Bellman-Ford算法的队列优化了
4反思:自己在t的变化上忽视了在每次循环中应使用两次t++,导致了有效数据被覆盖,数组一开始开小了,但自己感觉计算就应该是1<=n<=50000,1<=m<=200000,以后需要注意留心仔细一点
5尝试推测题意考察点,把握重点,注意细节
6刚才又学习了SPFA算法,用SPFA算法实现了一下,可能因为后台数据比较类型相似,两种算法实现的时间差不多,可能自己因为刚学习,一些SPFA算法的优化还不会,自己想同样加标记变量,结果可能加标记变量后一些位置重新松弛的时候变化不对,因此结果wrong answer,自己应该继续深入学习,争取学会SPFA算法很好的优化
7SPFA算法(Bellman-Ford算法的队列优化)
8Floyd算法的时间复杂度为O(N^3),Dijkstra算法的时间复杂度为O((M + N)logN),堆优化的Dijkstra算法时间复杂度可以达到O(MlogN),而Bellman-Ford算法的时间复杂度为O(NM),队列优化的Bellman-Ford算法时间复杂度最坏也是O(NM)
9Floyd算法和Dijkstra算法适合于稠密图,和顶点关系密切,而Bellman-Ford算法与队列优化的Bellman-Ford算法适合于稀疏图,和边关系密切
sdut原题链接
C–最短路
Time Limit: 7000MS Memory Limit: 65536KB
Problem Description
给出一个带权无向图,包含n个点,m条边。求出s,e的最短路。保证最短路存在。
Input
多组输入。
对于每组数据。
第一行输入n,m(1<= n && n<=5*10^5,1 <= m && m <= 2*10^6)。
接下来m行,每行三个整数,u,v,w,表示u,v之间有一条权值为w(w >= 0)的边。
最后输入s,e。
Output
对于每组数据输出一个整数代表答案。
Example Input
3 1
1 2 3
1 2
Example Output
3
Hint
Author
zmx
以下为accepted代码——Bellman-Ford
#include <stdio.h> #define INF 0x3f3f3f3f int dist[500004], u[4000004], v[4000004], w[4000004]; int main() { int n, m, i, k, s, e, check, flag, t, x, y, z; while(scanf("%d %d", &n, &m) != EOF) { t = 1; for(i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &z); u[t] = x, v[t] = y, w[t] = z; t++; u[t] = y, v[t] = x, w[t] = z; t++;///注意:使用之后一定要+1 } scanf("%d %d", &s, &e); for(i = 1; i <= n; i++) dist[i] = INF; dist[s] = 0; m = 2*m;//有权无向图 //Bellman-Ford算法核心语句 for(k = 0; k < n-1; k++) { check = 0; for(i = 1; i <= m; i++) { if(dist[v[i]] > dist[u[i]] + w[i]) { dist[v[i]] = dist[u[i]] + w[i]; check = 1; } } if(check == 0) break; } //检测负权回路 flag = 0; for(i = 1; i <= m; i++) { if(dist[v[i]] > dist[u[i]] + w[i]) flag = 1; } if(flag) printf("error because of -\n"); else printf("%d\n", dist[e]); } return 0; } /*************************************************** User name: Result: Accepted Take time: 808ms Take Memory: 36672KB Submit time: 2017-02-19 16:33:18 ****************************************************/
以下为accepted代码——SPFA算法
#include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f int tp, op; int book[500004], link[500004]; int dist[500004], u[4000004], v[4000004], w[4000004]; int main() { int n, m, i, k, s, e, t, x, y, z; while(scanf("%d %d", &n, &m) != EOF) { tp = op = 0; memset(book, -1, sizeof(book)); memset(link, 0, sizeof(link)); t = 1; for(i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &z); u[t] = x, v[t] = y, w[t] = z; t++; u[t] = y, v[t] = x, w[t] = z; t++; } scanf("%d %d", &s, &e); for(i = 1; i <= n; i++) dist[i] = INF; dist[s] = 0; m = 2*m; link[tp++] = v[s]; book[s] = 1; while(op < tp) { op++; k = link[op]; while(k <= m) { if(dist[v[k]] > dist[u[k]] + w[k]) { dist[v[k]] = dist[u[k]] + w[k]; if(book[k] == 0) { link[tp++] = v[k]; book[v[k]] = 1; } } k++; } } printf("%d\n", dist[e]); } return 0; } /*************************************************** User name: Result: Accepted Take time: 860ms Take Memory: 52840KB Submit time: 2017-02-19 17:49:05 ****************************************************/
相关文章推荐
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- 带权最短路 Dijkstra, SPFA, Bellman-Ford, ASP, Floyd-Warshall 算法分析
- 带权最短路 Dijkstra, SPFA, Bellman-Ford, ASP, Floyd-Warshall 算法分析
- 模板--Floyd Dijkstra Bellman-Ford spfa 四种最短路经典算法
- 最短路模版(floyed/dijkstra/bellman-ford/spfa)
- HDU 2544 最短路 floyd djkstra(邻接表,邻接矩阵) spfa bellman-ford 模板题
- (POJ 3259)Wormholes 判断负环 bellman_ford 或者 spfa
- 最短路知识点总结(Dijkstra,Floyd,SPFA,Bellman-Ford)
- HDU 2544 最短路(四种写法:Floyd、Dijkstra、Bellman-Ford、SPFA)
- 最短路(Floyd+Dijkstra+(Bellman-Ford)SPFA)
- POJ 3259 Wormholes (图论---最短路 Bellman-Ford || SPFA)
- 最短路知识点总结(Dijkstra,Floyd,SPFA,Bellman-Ford)
- SPFA or bellman ford松弛法--单源最短路
- Floyd Dijkstra Bellman-Ford spfa 四种最短路经典算法汇总 HDU 2544为例
- 带权最短路 Dijkstra, SPFA, Bellman-Ford, ASP, Floyd-Warshall 算法分析
- hdu1874(最短路:一道题学习Floyd,Dijkstra,Bellman-Ford,SPFA)
- 最短路 SPFA (对于bellman-ford 的优化)
- 最短路(SPFA、Dijkstra、Floyd、Bellman-Ford)
- POJ3259 Wormholes SPFA 或者 bellman_ford