【算法笔记】最短路总结
来源:互联网 发布:python实现朴素贝叶斯 编辑:程序博客网 时间:2024/06/06 06:31
次短路
目前只会用dijstra求解。。(貌似有用spfa的。。
当然如果是DAG, 拓扑排序加DP也是可以的。。
次短路的求解和计数
hdu 3191
这道题有边权为0的情况。
dij所使用的贪心性质:S是目标集合(已经求得最短路或次短路的点),从 V - S 中选估计值最小的一个u,那么
如果边权有0存在, 那么这条性质就无法保证了。。
幸而数据比较特殊, 只要保证编号小的点先更新就行了。。
// 这道题的数据里面有权值为0的情况,pq并不能保证正确// 详见 http://acm.hdu.edu.cn/discuss/problem/list.php?problemid=3191int n, m, src, dst;struct Edge { int v, w;};vector<Edge> graph[N];struct Node { int flag, d, i; bool operator < (const Node &rhs) const { if ( d != rhs.d ) return d > rhs.d; return i > rhs.i; }};const int INF = 1e9;int d[2][N], cnt[2][N];bool done[2][N];void dij() { memset(done, 0, sizeof(done)); memset(cnt, 0, sizeof(cnt)); fill(d[0], d[0] + n, INF); fill(d[1], d[1] + n, INF); d[0][src] = 0; cnt[0][src] = 1; d[1][src] = -1; priority_queue<Node> q; q.push( (Node) {0, 0, src} ); while(!q.empty()) { Node fr = q.top(); q.pop(); int u = fr.i, du = fr.d; if ( done[fr.flag][u] ) continue; done[fr.flag][u] = 1; for (int i = 0; i < graph[u].size(); ++i) { int v = graph[u][i].v, w = du + graph[u][i].w, num = cnt[fr.flag][u]; if ( d[0][v] > w ) { if ( d[0][v] != INF ) { d[1][v] = d[0][v]; cnt[1][v] = cnt[0][v]; q.push( (Node) {1, d[1][v], v} ); } d[0][v] = w; cnt[0][v] = num; q.push( (Node) {0, d[0][v], v} ); } else if ( !done[0][v] && d[0][v] == w ) { cnt[0][v] += num; } else if ( d[1][v] > w ) { cnt[1][v] = num; d[1][v] = w; q.push( (Node) {1, d[1][v], v} ); } else if ( !done[1][v] && d[1][v] == w ) { cnt[1][v] += num; } } } printf("%d %d\n", d[1][dst], cnt[1][dst]);}int main() {#ifdef _LOCA_ENV_ freopen("input.in", "r", stdin);#endif // _LOCA_ENV while ( scanf("%d%d%d%d", &n, &m, &src, &dst) != EOF ) { rep(i, 0, n-1) graph[i].clear(); rep(i, 1, m) { int x, y, w; scanf("%d%d%d", &x, &y, &w); graph[x].push_back( (Edge) {y, w} ); } dij(); } return 0;}
次短路拓展
lightoj 1099
求无向图上次短路值, 可以往回走。。
因为是无向图, 所以往回走并不影响什么。。
只要“往回走”得到的次短路比较优, 贪心性质一定会保证它被选中。
也可以不用done数组, 直接用值比较来判断这个点是否已经用来更新过了。。
int n, m, src, dst;struct Edge { int v, w;};vector<Edge> graph[N];struct Node { int flag, d, i; bool operator < (const Node &rhs) const { if ( d != rhs.d ) return d > rhs.d; return i > rhs.i; }};const int INF = 1e9;int d[2][N];bool done[2][N];void dij() { memset(done, 0, sizeof(done)); fill(d[0], d[0] + n, INF); fill(d[1], d[1] + n, INF); d[0][src] = 0; d[1][src] = INF; priority_queue<Node> q; q.push( (Node) {0, 0, src} ); while(!q.empty()) { Node fr = q.top(); q.pop(); int u = fr.i, du = fr.d; if ( done[fr.flag][u] ) continue; done[fr.flag][u] = 1; for (int i = 0; i < graph[u].size(); ++i) { int v = graph[u][i].v, w = du + graph[u][i].w; if ( d[0][v] > w ) { if ( d[0][v] != INF ) { d[1][v] = d[0][v]; q.push( (Node) {1, d[1][v], v} ); } d[0][v] = w; q.push( (Node) {0, d[0][v], v} ); } else if ( d[0][v] == w ) { // pass } else if ( d[1][v] > w ) { d[1][v] = w; q.push( (Node) {1, d[1][v], v} ); } } }}
Dijstra拓展
当最短路径有多条的时候, 我们可以倒过来递推出, 所有最短路径。
还可以对pq使用的HeapNode节点添加一些性质, 在不影响最短路值的情况下, 决定优先用哪些边来更新。
codeforces 449B - Jzzhu and Cities
在不影响1到各点最短路值的情况下, 尽量去掉 给定边集里面的边。
0 0
- 【算法笔记】最短路总结
- 最短路算法总结
- 最短路算法总结
- 最短路算法总结
- 最短路算法总结
- 最短路算法总结
- 最短路算法总结
- 算法总结:最短路
- 最短路算法总结
- Dijkstra算法笔记---最短路
- 数据结构算法笔记--最短路
- 最短路算法学习总结和感悟
- 最短路的四种算法总结
- 求最短路算法的一个总结
- |算法讨论|最短路 学习笔记
- [笔记]: 4个最短路算法
- 算法笔记---最短路路径之Floyd(弗洛伊德)算法
- JavaScript最短路算法
- 网络编程系列之九 getopt()函数
- C++怎么判断一个类存在指定的函数名的函数
- 各种加解密算法比较
- Qt中如何写一个model
- akoj-1291-决战21点(C#)
- 【算法笔记】最短路总结
- [Raspbian]开始用RaspberryPi构建小型家用资料共享服务器
- 详细介绍Linux shell脚本基础学习(五)
- 刚刚接触OPENCV,配置正确之后的运行过程
- 数据仓库与数据挖掘的OLAP技术----韩家炜教授的《数据挖掘概念与技术》学习笔记
- x64 antidebug 不触发PG 补充代码
- 详细介绍Linux shell脚本基础学习(六)
- 除去ScrollVIew拉到尽头时再拉的阴影效果和个别机型的阻尼效果
- 详细介绍Linux shell脚本基础学习(七)