📜  门|门CS 2008 |问题 14(1)

📅  最后修改于: 2023-12-03 15:12:47.155000             🧑  作者: Mango

门|门CS 2008 |问题 14

这是一道关于图论的考察题目,需要求出两个节点之间的最短路径,使用的算法是Dijkstra算法。

问题描述

有一个n个节点m条边的有向图,请你求出从节点1到节点n的最短路径。如果不存在从1到n的路径,输出-1。

输入格式

第一行包含两个整数n和m。

接下来m行,每行包含三个整数a,b,c,表示存在一条从节点a到节点b的边,边长为c。

输入样例
3 3
1 2 1
2 3 2
1 3 3
输出样例
3
代码实现
|```c++
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 2010, M = 6010;

struct Edge{
    int to, w, nxt;
}edges[M];

int head[N], dis[N];
bool vis[N];
int n, m, idx;

void add_edge(int u, int v, int w){
    edges[idx] = {v, w, head[u]};
    head[u] = idx ++;
}

void Dijkstra(){
    memset(dis, 0x3f, sizeof(dis));
    dis[1] = 0;

    for(int i = 0; i < n; i ++){
        int u = -1;
        for(int j = 1; j <= n; j ++){
            if(!vis[j] && (u == -1 || dis[u] > dis[j])){
                u = j;
            }
        }

        vis[u] = true;

        for(int j = head[u]; j != -1; j = edges[j].nxt){
            int v = edges[j].to;
            if(dis[v] > dis[u] + edges[j].w){
                dis[v] = dis[u] + edges[j].w;
            }
        }
    }
}

int main(){
    cin >> n >> m;

    memset(head, -1, sizeof(head));
    for(int i = 0; i < m; i ++){
        int u, v, w;
        cin >> u >> v >> w;
        add_edge(u, v, w);
    }

    Dijkstra();

    if(dis[n] == 0x3f3f3f3f) cout << -1 << endl;
    else cout << dis[n] << endl;

    return 0;
}
|```
代码说明

该题是一道典型的图论问题,使用Dijkstra算法求解最短路径。首先需要定义图的数据结构,每条边都要记录下来,这里使用的是邻接表存储。算法的实现过程中需要重点注意每个变量的含义与作用。