POJ 3255 Roadblocks(Dijkstra)

61 篇文章 0 订阅

Description
在一个图上有许多个农场,有个人从1农场出发,到他的朋友n农场去,他不想走一条最短路径,这次他想换条路走,要你帮他找一条次短路径,次短路的定义是,比最短路径长度短(可能有多条),但是不会比其他的路径长度长。而且告诉你数据中一定存在至少一条次短路。
Input
第一行两个整数n和r分别表示农场个数和路径条数,之后r行每行三个整数a,b,d表示a农场与b农场之间有一条长度为d的路径
Output
输出次短路长度
Sample Input
4 4
1 2 100
2 4 200
2 3 250
3 4 100
Sample Output
450
Solution
利用最短路的思想,最短路是维护每个节点到起点的最短距离,每次确定未确定里面距离最短的那个节点的最短距离,根据次短路定义,从S到u的第二短的路线,那么只要维护一下次短路就可以了
Code

#include<iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<memory.h>
#include<fstream>
using namespace std;
const int INF=1<<29;
const int nMax=10000;
struct edge{
    edge(){}
    edge(int x,int y)
    {
        cost=x;
        to=y;
    }
    bool operator<(const edge& rhs)const
    {
        return cost>rhs.cost;
    }
    int cost;
    int to;
};
vector<edge>node[nMax];
int dist1[nMax];//最短路 
int dist2[nMax];//次短路 
void dijkstra(int s)
{
    for(int i=0;i<nMax;++i)//初始化 
        dist1[i]=INF;   
    for(int i=0;i<nMax;++i)//初始化 
        dist2[i]=INF;   
    dist1[s]=0;
    priority_queue<edge,vector<edge> > q;
    q.push(edge(0,s));
    edge u;
    while(!q.empty())
    {
        u=q.top();
        q.pop();
        int sz=node[u.to].size();
        int v=u.to;
        if(u.cost>dist2[v])
            continue;
        for(int i=0;i<sz;++i)
        {
            int next=node[v][i].to;
            int d=node[v][i].cost+u.cost;
            if(d<dist1[next])//维护最短路 
            {
                swap(d,dist1[next]);
                q.push(edge(dist1[next],next));
            }
            if(d>dist1[next]&&d<dist2[next])//维护次短路 
            {
                dist2[next]=d;
                q.push(edge(dist2[next],next));
            }   
        }
    }
}
int main()
{
    int n,r;
    cin>>n>>r;
    int x,y,cost;
    for(int i=0;i<r;++i)
    {
        cin>>x>>y>>cost;
        node[x].push_back(edge(cost,y));//路是双向的 
        node[y].push_back(edge(cost,x));
    }
    dijkstra(1);
    printf("%d\n",dist2[n]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值