POJ 3255 Roadblocks --次短路径

由于次短路一定存在,则可知次短路一定是最短路中某一条边不走,然后回到最短路,而且只是一条边,两条边以上不走的话,就一定不会是次短路了(即以边换边才能使最小)。所以可以枚举每一条边,算出从起点到这条边起点的最短距离,以及从终点到这条边终点的最短距离,再加上这条边的权值,看是否是次短路(比最短路总权值大的最小权值的路径)

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define Mod 1000000007
using namespace std;
#define N 5007

vector<pair<int,int> > G[200005];
int ds[N],dt[N],vis[N];
int n,m,k;

void SPFA(int s,int *d)
{
    int i,u,v;
    queue<int> que;
    memset(vis,0,sizeof(vis));
    d[s] = 0;
    vis[s] = 1;
    que.push(s);
    while(!que.empty())
    {
        v = que.front();
        que.pop();
        vis[v] = 0;  //边允许重复走
        for(i=0;i<G[v].size();i++)
        {
            u = G[v][i].first;
            if(d[v] + G[v][i].second < d[u])
            {
                d[u] = d[v] + G[v][i].second;
                if(!vis[u])
                {
                    vis[u] = 1;
                    que.push(u);
                }
            }
        }
    }
}

int main()
{
    int u,v,w;
    int res,tmp,i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
            G[i].clear();
        for(i=1;i<=n;i++)
            ds[i] = dt[i] = Mod;
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            G[u].push_back(make_pair(v,w));
            G[v].push_back(make_pair(u,w));
        }
        SPFA(1,ds);
        SPFA(n,dt);
        res = Mod;
        for(i=1;i<=n;i++)
            for(j=0;j<G[i].size();j++)
            {
                u = i;
                v = G[i][j].first;
                w = G[i][j].second;
                tmp = ds[u] + dt[v] + w;
                if(tmp > ds[n] && res > tmp)
                    res = tmp;
            }
        printf("%d
",res);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/whatbeg/p/3642231.html