题目描述
给定一个 nnn 个点,mmm 条有向边的带非负权图,请你计算从 sss 出发,到每个点的距离。
数据保证你能从 sss 出发到任意点。
输入格式
第一行为三个正整数 n,m,sn, m, sn,m,s。 第二行起 mmm 行,每行三个非负整数 ui,vi,wiu_i, v_i, w_iui,vi,wi,表示从 uiu_iui 到 viv_ivi 有一条权值为 wiw_iwi 的有向边。
输出格式
输出一行 nnn 个空格分隔的非负整数,表示 sss 到每个点的距离。
输入输出样例
输入 #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#include<iostream>#include<stdio.h>#include<queue>#include<algorithm>#define WQD 2147483647#define maxn 10000001using namespace std;struct VD{ int v,d; bool operator<(const VD&a)const { return a.d<d; }};struct Edge{ int to,w,next;};Edge edge[maxn];int head[maxn],u,v,d,dis[maxn],m,n,S,num=0;void add(int from,int to,int di){ edge[++num].next=head[from]; edge[num].to=to; edge[num].w=di; head[from]=num;}void dijkstra(int s){ priority_queue<VD>q; for(int i=1;i<=n;i++) dis[i]=WQD; dis[s]=0; VD temp; temp.d=dis[s];temp.v=s; q.push(temp); while(!q.empty()) { temp=q.top(); q.pop(); int p=temp.v; if(dis[p]<temp.d) continue; for(int i=head[p];i!=0;i=edge[i].next) if(dis[edge[i].to]>dis[p]+edge[i].w) { dis[edge[i].to]=dis[p]+edge[i].w; temp.v=edge[i].to;temp.d=dis[edge[i].to]; q.push(temp); } } return;}int main(){ cin>>n>>m>>S; for(int i=1;i<=m;i++) {cin>>u>>v>>d; add(u,v,d); } dijkstra(S); for(int i=1;i<=n;i++) cout<<dis[i]<<' '; return 0;}单源最短路dijkstra算法模板;void dijkstra(int s){ priority_queue<VD>q; for(int i=1;i<=n;i++) dis[i]=WQD; dis[s]=0; VD temp; temp.d=dis[s];temp.v=s; q.push(temp); while(!q.empty()) { temp=q.top(); q.pop(); int p=temp.v; if(dis[p]<temp.d) continue; for(int i=head[p];i!=0;i=edge[i].next) if(dis[edge[i].to]>dis[p]+edge[i].w) { dis[edge[i].to]=dis[p]+edge[i].w; temp.v=edge[i].to;temp.d=dis[edge[i].to]; q.push(temp); } } return;}用优先队列每次取最短的边遍历,优化时间;if(dis[p]<temp.d) continue;判断该temp对应的dis是否是该点最短路,若不是继续下一个点,减少遍历次数,优化了时间;