次最短路径 POJ 3255 Roadblocks

时间:2023-03-09 08:51:59
次最短路径 POJ 3255 Roadblocks

http://poj.org/problem?id=3255

这道题还是有点难度

要对最短路径的算法非常的了解 明晰 那么做适当的修改 就可以

关键之处 次短的路径: 设u 到 v的边权重为cost

那么到v的次短路径要么是 到u的次短路径+cost;要么是到u的最短路径+cost;

那么就在dijkstra中 既要保存 最短路径的数组 又要 保存次短路径的情况

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#define MAXV 5007
#define MAXE 200007
#define INF 0x3f3f3f3f
//向前星 125ms
using namespace std;
typedef pair<int,int> P; int E, V;
struct Edge
{
int to, cost, next;
Edge () {}
Edge (int to, int cost, int next) : to(to), cost(cost), next(next) {}
}edge[MAXE];
int head[MAXV];
int num = ;
void Add(int from, int to, int cost)
{
edge[num] = Edge(to, cost, head[from]);
head[from] = num++;
} int dijkstra()
{
int dist1[MAXV], dist2[MAXE];
priority_queue<P, vector<P>, greater<P> > que;
fill(dist1, dist1+MAXV, INF);
fill(dist2, dist2+MAXV, INF);
dist1[] = ;
que.push(P(dist1[], ));
while (!que.empty())
{
P p = que.top();
que.pop();
int v = p.second, d = p.first;
if (dist2[v] < d) continue;//如果次短路径都小于d 那么就不用再继续去更新
int t = head[v];
while (t != -)
{
Edge e = edge[t];
int d2 = e.cost + d;//到e.to的假设次短距离 是到v的最距离 + e.cost
if(d2 < dist1[e.to])//如果次短路小于最短路 交换最短路和次短路
{
swap(dist1[e.to], d2);
que.push(P(dist1[e.to], e.to));
}
if (d2 < dist2[e.to] && d2 > dist1[e.to])//如果可以更新次短路
{
dist2[e.to] = d2;
que.push(P(dist2[e.to], e.to));//这两句if 体现次短路 要么是到达其他某个顶点的最短路加上u->v这条边,要么是到u的次短路再加上u->v这条边
}
t = e.next;
}
}
return dist2[V];
} int main()
{
freopen("in.txt", "r", stdin);
scanf("%d%d", &V, &E);
memset(head, -, sizeof(head));
memset(edge, -, sizeof(edge));
for (int i = ; i < E; i++)
{
int from, to, cost;
scanf("%d%d%d", &from, &to, &cost);
Add(from, to, cost);
Add(to, from, cost);
}
int ans = dijkstra();
//cout << ans << endl;
printf("%d\n", ans);
}