【模板】单源最短路径(标准版)

题目描述

给定一个 N 个点,M 条有向边的带非负权图,请你计算从 SS 出发,到每个点的距离。

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

输入输出格式

输入格式:

第一行为三个正整数 N, M, S。 第二行起 M 行,每行三个非负整数 u_i, v_i, w_i,表示从 u_i到 v_i有一条权值为 w_i 的边。

输出格式:

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

输入输出样例

输入样例#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

说明

1N100000;

1M200000;

S=1;

1ui,viN;

0wi109,

0wi≤10 ^ 9

分析:

本题就更是一道模板题了。。。但是专门卡SPFA和无堆优化的dijkstra,真是一道毒瘤题。。。所以必须敲堆优化的dijkstra。具体见下方代码。

CODE:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int M=1000005;
 9 const int oo=2147483647;
10 int n,m,tot,s;
11 int next[M],head[M],to[M],adj[M],dist[M];
12 struct node{
13     int id,d;
14     bool operator> (const node b) const {return d>b.d;}
15 }a[M];
16 priority_queue <node,vector<node>,greater<node> > Q;
17 void add(int u,int v,int w){
18     next[++tot]=head[u];
19     head[u]=tot;
20     to[tot]=v;
21     adj[tot]=w;
22     return;
23 }
24 void dijkstra(){
25     for (int i=1;i<=n;i++) 
26     dist[i]=oo;
27     dist[s]=0;
28     Q.push((node){s,0});
29     while (!Q.empty()){
30         node top=Q.top();
31         Q.pop();
32         if (top.d!=dist[top.id]) 
33         continue;
34         for (int i=head[top.id];i;i=next[i])
35             if (top.d+adj[i]<dist[to[i]]){
36                 dist[to[i]]=top.d+adj[i];
37                 Q.push((node){to[i],dist[to[i]]});
38             }
39     }
40     return;
41 }
42 int main(){
43     cin>>n>>m>>s;
44     for (int i=1;i<=m;i++){
45         int u,v,w;
46         cin>>u>>v>>w;
47         add(u,v,w);
48     }
49     dijkstra();
50     for (int i=1;i<=n;i++) 
51     cout<<dist[i]<<" ";
52     return 0;
53 }
原文地址:https://www.cnblogs.com/kanchuang/p/11120033.html