题目描述
给定一个 NN 个点,MM 条有向边的带非负权图,请你计算从 SS 出发,到每个点的距离。

数据保证你能从 SS 出发到任意点。

输入格式
第一行为三个正整数 N, M, SN,M,S。 第二行起 MM 行,每行三个非负整数 u_i, v_i, w_iu
i
​ ,v
i
​ ,w
i
​ ,表示从 u_iu
i
​ 到 v_iv
i
​ 有一条权值为 w_iw
i
​ 的边。

输出格式
输出一行 NN 个空格分隔的非负整数,表示 SS 到每个点的距离。

输入输出样例
输入 #1 复制
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出 #1 复制
0 2 4 3
说明/提示
样例解释请参考 数据随机的模板题。

1 \leq N \leq 1000001≤N≤100000;

1 \leq M \leq 2000001≤M≤200000;

S = 1S=1;

1 \leq u_i, v_i\leq N1≤u
i
​ ,v
i
​ ≤N;

0 \leq w_i \leq 10 ^ 90≤w
i
​ ≤10
9
,

0 \leq \sum w_i \leq 10 ^ 90≤∑w
i
​ ≤10
9

本题数据可能会持续更新,但不会重测,望周知。

2018.09.04 数据更新 from @zzq

链式前向星的模板,可以过本题。第二个代码是vector建图的模板,不卡常的情况下很好使。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb std::ios::sync_with_stdio(false)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define gg(x) getInt(&x)
using namespace std;
typedef long long ll;
inline void getInt(int* p);
/*** TEMPLATE CODE STARTS HERE ***/
const int maxn=100010;
const int MAXM=200000;
// const int INF= 0x3f3f3f3f;

struct Edge
{
    int to,next;
    ll dist;
    Edge(){}
    Edge(int tt,ll dd)
    {
        to=tt;
        dist=dd;
    }
    bool operator < (const Edge x ) const
    {
        return dist > x.dist;
    }
}edge[MAXM];
int head[maxn],tot;
void addedge(int u,int v,ll c)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    edge[tot].dist=c;
    head[u] = tot++;
}
priority_queue<Edge> heap;
ll dis[maxn];
int t,n,star;
bool vis[maxn];
void dijkstra (int strat)
{
    // memset(dis,INF,sizeof(dis));
    repd(i,1,n)
    {
        dis[i]=1e18;
        vis[i]=0;
    }
    dis[strat]=0;
    heap.push(Edge(strat,dis[strat]));
    while(!heap.empty())
    {
        Edge x= heap.top();
        heap.pop();
        int u=x.to;
        if(vis[u])
        {
            continue;
        }
        vis[u]=1;
        for(int i = head[u];i != -1;i = edge[i].next)
        {
            Edge now = edge[i];
            if(dis[now.to]>x.dist+now.dist)
            {
                dis[now.to]=x.dist+now.dist;
                heap.push(Edge(now.to,dis[now.to]));
            }
        }
    }

}
int main()
{
    scanf("%d %d %d",&n,&t,&star);
    int a,b,d;
    memset(head,-1,sizeof(head));
    repd(i,1,t)
    {
        scanf("%d %d %d",&a,&b,&d);
        addedge(a,b,d);
    }
    dijkstra(star);
    repd(i,1,n)
    {
        printf("%lld ",dis[i]);
    }

    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}

``` cpp