一日一题:第一题---Dijkstra求最短路 I(最浅显易懂!)

分享—对于最短路问题的笔记:

一日一题:第一题---Dijkstra求最短路 I(最浅显易懂!)_第1张图片

戳这里->原题链接

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

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

输入格式
第一行包含整数 n 和 m 。

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

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

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

数据范围
1 ≤ n ≤ 500 
1 ≤ m ≤ 10^5 
图中涉及边长均不超过 10000。

输入样例:

3 3
1 2 2
2 3 1
1 3 4

输出样例:

3
#include
using namespace std;

const int N=510;
int n,m;
int g[N][N];//输入的边与边的距离
int dist[N];//储存从1号点开始到每条边的距离
bool st[N];//这个点是否被打通(就是是非被当过最优点已被确定过)

int dijkstra()
{
    memset(dist,0x3f3f3f3f,sizeof dist);//先相当于在每个路中间砌一个墙
    dist[1]=0;
    for(int i=1;idist[j]))
                t=j;
        }
        st[t]=true;
        for(int j=1;j<=n;j++)
//如果被作为最优点,就相当于此点被打通,你就看看通过这个点,到其他点的是否比之前短,如果满足就先作为最短路径先更新进来随后还会进行判断
            dist[j]=min(dist[j],dist[t]+g[t][j]);
        if(t==n) break;
//如果我们要查找的n号点已经被更新为最优点就说明最短距离已经被发现(因为咱们边的权值都为正,不可能还有到n最短的了,可以跳出来了)
    }
    if(dist[n]==0x3f3f3f3f)return -1;//如果打通的点也无法到达我们要找的n时,就说明到不了了
    return dist[n];
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(g,0x3f,sizeof g);//当时我在想可以不写这个嘛,然后我突然想到,如果你让g默认为0,你从1->2可能会等于1->2->3,哪怕2->3根本没有路,但由于g[2][3]=0,所以路线也可能会更新,所以要设为最大值,就像堵墙档着。
    
    
    for(int i=0;ic)//因为题目说有重边和自环,所以要更新最优距离
            g[a][b]=c;
        //min(g[a][b],c);两种都可以
    }
    int s=dijkstra();
    cout<

查漏补缺:

知识点一:

0x3f: int型的数据是占4个字节,32位,就是 2^32

        而0x3f就是 2^6=64,显然是不满足int的需求

0x3f3f3f3f: 就已经是10^9级别的了,一般情况下很少有数据能够超过它,用来表示无穷大足够了

知识点二:

当点数和边数的关系是n的级别,呢我们就可以说这是稀疏图,使用邻接表的方法

当点数和边数的关系是n方的级别,呢我们就可以说这是稠密图,使用邻接矩阵的方法

 总结:刚开始被搞得米米,发现了个刷题妙招,不会就敲,再不会就背,不出两天就差不多理解了。

欢迎来到一日一题的小菜鸟频道,睡不着就看看吧!

跟着小张刷题吧!

你可能感兴趣的:(一日一题,c++,算法,图论)