Dijkstra求最短路(1)

描述

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。

image.png

输入

第一行包含整数n和m。

接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。

输出

输出一个整数,表示1号点到n号点的最短距离。

如果路径不存在,则输出-1。

输入样例 
3 3
1 2 2
2 3 1
1 3 4
输出样例

3

代码实现

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
#define Inf 0x3f3f3f3f
const int N=150005;
typedef pair<int,int> PII;
typedef struct Enode* Arc;

struct Enode
{
    Enode(int b=0,int c=0):y(b),z(c),next(NULL){}
    int y,z;
    Arc next;
};
Arc Ge[N];
int Dist[N]={0};
void Add(int x,Arc newnode)
{
    if(Ge[x])
    {
        Arc temp=Ge[x];
        while(temp->next)temp=temp->next;
        temp->next=newnode;
    }
    else Ge[x]=newnode;
}
void Dijkstra(int);
int n,m;
int main()
{
    for(int i=0;i<N;i++){Ge[i]=NULL;Dist[i]=Inf;}
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        scanf("%d %d %d",&x,&y,&z);
        if(x!=y)
        {
            Arc newnode=new Enode(y,z);
            Add(x,newnode);
        }
    }
    Dijkstra(1);
    return 0;
}
void Dijkstra(int source)
{
    priority_queue<PII,vector<PII>,greater<PII>> q;
    //Dist[source]=0;
    q.push({0,source});
    while(!q.empty())
    {
        auto t=q.top();
        q.pop();
        int x=t.second;
        int u=t.first;
        if(Dist[x]<=u)continue;
        else
        {
            Dist[x]=u;
            Arc temp=Ge[x];
            while(temp)
            {
                q.push({u+temp->z,temp->y});
                temp=temp->next;
            }
        }
    }
    if(Dist[n]==Inf)cout<<-1<<endl;
    else cout<<Dist[n]<<endl;
}

请注意priority_queue是一种容器适配器,需要指定一个容器类型来存储队列中的元素,本题使用greater将队列q指定为一个最小堆。

priority_queue<ContainerValueType, Container, Compare>

这题我在编写时出了一个问题,当我尝试用自定义的结构体定义优先队列的排序规则时,以下情况会超时①。

struct Compare {
    bool operator()(const PII& a, const PII& b) {
        return a.first < b.first; // 比较pair的第一个元素
    }
};

而改为以下形式②时,却可以通过测试点,那么是什么导致上一种代码测试点运行超时呢?

struct Compare {
    bool operator()(const PII& a, const PII& b) {
        return a.first > b.first; // 比较pair的第一个元素
    }
};

于是我上网查了优先队列的资料,发现②形式才能实现最小堆,也就是说优先队列内部的逻辑应该如下。其中less为大堆,而Greater代表小堆。也就是说在定义优先队列数据结构<x,y>时,y的优先级高于x的优先级,注意与sort算法区分。

template <class T>
class Less
{
public:
	bool operator()(const T& x, const T& y)
	{
 
		return x < y;
	}
};
 
template<class T>
class Greater
{
public:
	bool operator()(const T& x, const T& y)
	{
		return x > y;
	}
};

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值