您的位置:首页 > 其它

最短路算法及其延伸

2015-11-09 21:14 423 查看
个人算法训练题集:http://acm.hust.edu.cn/vjudge/contest/toListContest.action#contestType=0&contestRunningStatus=0&contestOpenness=0&title=风斩冰华&manager=

密码xwd,欢迎大家一起来学习。

首先复习一下最短路问题,即求某两点之间边权最小的一条路径。这样就延伸出了两个子问题:

求任意两点的距离,还是求图上固定一个起点到某点的距离?

验题:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85798#problem/A

任意两点的距离

求任意两点的距离可以用floyd算法,类似于Warshell算法求传递闭包,我认为是在图上加了一条虚边,使得这条虚边是最短路径而已。floyd算法的基本思想是贪心(DP貌似也说得过去),给出(状态转移方程?)G[i][j] = max(G[i][j], G[i][k]+G[k][j]) 以及代码:

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>

using namespace std;

typedef struct E {
int w;
int v;
E() {}
E(int vv, int ww) : v(vv), w(ww) {}
}E;

typedef pair<int, int> PII;
const int maxn = 5555;
const int inf = 0xffffff;

priority_queue<PII, vector<PII>, greater<PII> > pq;
vector<E> e[maxn];
int d1[maxn], d2[maxn];
int n, m, u, v, w;

void dijkstra(int s) {
for(int i = 0; i <= n; i++) d1[i] = d2[i] = inf;
while(!pq.empty()) pq.pop();
d1[s] = 0;
pq.push(PII(0, s));
while(!pq.empty()) {
PII cur = pq.top(); pq.pop();
w = cur.first;
v = cur.second;
if(d2[v] < w) continue;
for(int i = 0; i < e[v].size(); i++) {
int dd = w + e[v][i].w;
if(d1[e[v][i].v] > dd) {
swap(d1[e[v][i].v], dd);
pq.push(PII(d1[e[v][i].v], e[v][i].v));
}
if(d2[e[v][i].v] > dd && dd > d1[e[v][i].v]) {
d2[e[v][i].v] = dd;
pq.push(PII(d2[e[v][i].v], e[v][i].v));
}
}
}
}

int main() {
// freopen("in", "r", stdin);
while(~scanf("%d %d", &n, &m)) {
for(int i = 0; i < m; i++) {
scanf("%d %d %d", &u, &v, &w);
e[u].push_back(E(v, w));
e[v].push_back(E(u, w));
}
dijkstra(1);
printf("%d\n", d2
);
}
}


小根堆优化dijkstra次短路

【转载请声明作者及出处,谢谢】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: