题目背景
2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。
然后呢?
最终,他因此没能与理想的大学达成契约。
小 F 衷心祝愿大家不再重蹈覆辙。
题目描述
给定一个 n 个点,m 条有向边的带非负权图,请你计算从 s 出发,到每个点的距离。
数据保证你能从 s 出发到任意点。
输入格式
第一行为三个正整数 n, m, s。 第二行起 m 行,每行三个非负整数 ui,vi,wi,表示ui 到vi 有一条权值为wi 的有向边。
输出格式
输出一行 n 个空格分隔的非负整数,表示 s到每个点的距离。
注意:这是一个有向图!!! (存成无向图,36分 d了半个小时,结果删了一行代码就ac了)
因为是模版题,其实和标准Dijkstra的思想差不多,具体详解参照 最短路问题-- Dijkstra Choose the best route
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=500005; 4 long long n,m,s,t; 5 long long u,v,w; 6 priority_queue< pair<int ,int > >q; int dis[N],vis[N]; 7 int read() 8 { 9 int x = 1,a = 0; 10 char ch = getchar(); 11 while(ch < '0' || ch > '9'){ 12 if(ch == '-')x = -1; 13 ch = getchar(); 14 } 15 while(ch <= '9'&&ch >= '0'){ 16 a = a * 10 + ch - '0'; 17 ch = getchar(); 18 } 19 return x*a; 20 } 21 struct node 22 { 23 int val; 24 int to; 25 int next; 26 }e[N]; 27 int head [N]; 28 int tot =0; 29 void add (int u,int v,int w) 30 { 31 e[++tot].val=w; 32 e[tot].to=v; 33 e[tot].next=head[u]; 34 head[u]=tot; 35 } 36 void Dijkstra(int S) 37 { 38 q.push(make_pair(0,S)); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[S] = 0; 39 while(!q.empty()) 40 { 41 int x = q.top().second; 42 q.pop(); 43 if(vis[x]) 44 continue; 45 vis[x] = 1; 46 for(int i=head[x];i!=0;i=e[i].next) 47 { 48 int to1=e[i].to; 49 if(dis[to1] > dis[x] + e[i].val) 50 { 51 dis[to1] = dis[x] + e[i].val ; 52 q.push(make_pair(-dis[to1],to1)); 53 } 54 } 55 } 56 return; 57 } 58 int main() 59 { 60 n=read(); 61 m=read(); 62 s=read(); 63 for (int i = 1;i <= m;i++) 64 { 65 u=read(); 66 v=read(); 67 w=read(); 68 add(u,v,w); 69 } 70 Dijkstra(s); 71 for (int i = 1;i <= n;i++) 72 cout<<dis[i]<<" "; 73 return 0; 74 }