现在的位置: 首页 > 综合 > 正文

POJ3255 Roadblocks , 次短路

2018年12月24日 ⁄ 综合 ⁄ 共 1303字 ⁄ 字号 评论关闭

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

题意:某街区共有R条道路、N个路口。道路可以双向通行。问1号路口到N号路口的次短路长度是多少次短路指的是比最短路长度长的次短的路径。同一条边可以经过多次。


解法一:
     用最短路算法,在距离更新的时候,同时更新最短距离和次短距离。
解法二:
     先求出起点到所有点的最短距离d1[]和终点到所有点的最短距离d2[], 然后枚举每条边(双向边),即假定这条边在次短路中,记录每次的结果,这样最后就能得出次短的距离。
     ans = min(ds[v] + dt[u] + value[v][u]) e(v,u)∈ E
解法三:
     用求第k短路算法做。例题:POJ 2449 Remmarguts' Date


--------------------------------------------------------------------------------------------

解法一代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int maxn = 5000 + 10;
const int INF = 1000000000;
typedef pair<int, int> P;
int N, R;
struct edge {
    int to, cost;
};
vector<edge> G[maxn];
int dist[maxn];
int dist2[maxn];
void solve() {
    priority_queue<P, vector<P>, greater<P> > que;
    fill(dist, dist+N, INF);
    fill(dist2, dist2+N, INF);
    dist[0] = 0;
    que.push(P(0,0));
    while(!que.empty()) {
        P p = que.top();
        que.pop();
        int v = p.second, d = p.first;
        if(dist2[v] < d) continue;
        for(int i=0; i<G[v].size(); ++i) {
            edge &e = G[v][i];
            int d2 = d + e.cost;
            if(dist[e.to]>d2) {
                swap(dist[e.to], d2);
                que.push(P(dist[e.to], e.to));
            }
            if(dist2[e.to] >d2&&dist[e.to] <d2) {
                dist2[e.to] = d2;
                que.push(P(dist2[e.to], e.to));
            }
        }
    }
    printf("%d\n",dist2[N-1]);
}

int main() {
    int i, a, b, c;
    edge e;
    while(~scanf("%d%d",&N,&R)) {
        for(i=0; i<R; ++i) {
            scanf("%d%d%d", &a, &b, &c);
            a--,b--;
            e.to = b, e.cost = c;
            G[a].push_back(e);
            e.to = a;
            G[b].push_back(e);
        }
        solve();
    }
    return 0;
}

抱歉!评论已关闭.