题目链接:https://syzoj.com/problem/5
内存限制:128 MiB 时间限制:1000 ms

题目描述

有 n 个 城市,从1到n给他们编号,它们之间由一些单向道路(即一条道路只能从一个方向走向另一个方向,反之不行)相连,每条路还有一个花费c(i),表示通过第i条边需要花费c(i)的时间。
现在要求从1走到n。问最少需要多少时间。

输入格式

第一行两个整数n和m,表示有多少个城市和多少条道路。
接下来m行,每行两个整数u、v、c,即有一条从u到v需要花费时间c的道路。

输出格式

一行一个整数,即从1到n最少需要多少时间。

输入样例

4 5
1 2 20
1 3 10
3 2 5
2 4 7
3 4 15

输出数据

22

数据范围与提示

70%的数据,1<=n,m<=1000
100%的数据,1<=n,m<=100000

解题思路

最短路模板问题。

#include <queue>
#include <cstring>
#include <iostream>
#define MAXN 100005 
using namespace std;
struct edge {
    int u, v, w;
}e[MAXN];
int cnt, f[MAXN], dis[MAXN], vis[MAXN];
void Add(int u, int v, int w) {
    e[++cnt] = (edge){f[u], v, w};
    f[u] = cnt;
}
void Spfa(int s) {
    queue <int> Q;
    Q.push(s);
    dis[s] = 0;
    vis[s] = 1;
    while (!Q.empty()) {
        int t = Q.front();
        Q.pop();
        vis[t] = 0;
        for (int i = f[t]; i; i = e[i].u) {
            int v = e[i].v;
            if (dis[v] > dis[t] + e[i].w) {
                dis[v] = dis[t] + e[i].w;
                if (!vis[v]) {
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
}
int main() {
    int n, m, s, t, w;
    while (cin >> n >> m) {
        cnt = 0;
        memset(f, 0, sizeof(f));
        memset(vis, 0, sizeof(vis));
        memset(dis, 0x3f, sizeof(dis));
        for (int i = 0; i < m; i++) {
            cin >> s >> t >> w;
            Add(s, t, w);
        }
        Spfa(1);
        cout << dis[n] << endl;
    }
    return 0;
}