POJ 3255 Roadblocks 用dijkstra求次短路

用dijkstra求次短路

基本步骤和dijkstra求最短路径没有什么本质上的区别,就是定义两个数组进行更新

题目大意

第一行给出,顶点个数和路径个数,然后是路径的给出,是无向图要存两遍。求给出的路径中,从1~n 的第二短路径的长度。

题目分析

1.这次不是用一般的二维数组存,使用了一下stl里面的vector容器,pair函数,优先队列,时间复杂度明显降低。
vector<类型> 名字;//基本push_back存图操作,配合结构体使用
typedef pair<类型,类型> 名字;
//这里用这个是用来存,first是最短路径,second是用来存相应序号;
就是这些容器的读入,遍历等还是要足够熟练才好
2.次短路的产生依赖于最短路,所以其实本质上还是找 最短路,然后多以步骤更新次短路。

解题代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#define inf 0x3f3f3f3f
#define ll long long
#define maxn 100005
#define mod 1000000007
using namespace std;
struct edge{

    int to;
    int cost;
    edge (int ito,int icost)
    {
        to=ito;
        cost=icost;
    }
};
typedef pair<int,int> p;
vector<edge> g[maxn];
int dis1[maxn];
int dis2[maxn];
int n,r;
int dij()
{
    memset(dis1,inf,sizeof(dis1));
    memset(dis2,inf,sizeof(dis2));
    priority_queue<p,vector<p>,greater<p> > que;
    dis1[1]=0;
    que.push(p(dis1[1],1));
    while(!que.empty())
    {
        p tem=que.top();
        que.pop();
        int v=tem.second;
        int d=tem.first;
        if(dis2[v]<d)
        continue;
        for(int i=0;i<g[v].size();i++)
        {
            edge e=g[v][i];
            int hh=e.cost+d;
             if(hh<dis1[e.to])
             {
                 swap(hh,dis1[e.to]);
                 que.push(p(dis1[e.to],e.to));
             }
             if(hh<dis2[e.to])
             {
                 swap(hh,dis2[e.to]);
                 que.push(p(dis2[e.to],e.to));

             }
        }


    }
    return dis2[n];
}
int main()
{
    scanf("%d%d",&n,&r);

    for(int i=0;i<r;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a].push_back(edge(b,c));
        g[b].push_back(edge(a,c));

    }
    int ans=dij();
    printf("%d\n",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值