题目描述
给定一个 $n$ 个点,$m$ 条有向边的带非负权图,请你计算从 $s$ 出发,到每个点的距离。
数据保证你能从 $s$ 出发到任意点。
输入格式
第一行为三个正整数 $n, m, s$。
第二行起 $m$ 行,每行三个非负整数 $u_i, v_i, w_i$,表示从 $u_i$ 到 $v_i$ 有一条权值为 $w_i$ 的有向边。
输出格式
输出一行 $n$ 个空格分隔的非负整数,表示 $s$ 到每个点的距离。
样例
样例输入 #1
1 2 3 4 5 6 7
| 4 6 1 1 2 2 2 3 2 2 4 1 1 3 5 3 4 3 1 4 4
|
样例输出 #1
提示
$1 \leq n \leq 10^5$;
$1 \leq m \leq 2\times 10^5$;
$s = 1$;
$1 \leq u_i, v_i\leq n$;
$0 \leq w_i \leq 10 ^ 9$,
$0 \leq \sum w_i \leq 10 ^ 9$。
算法分析
使用堆优化(优先队列)
1 2 3 4 5 6 7 8
| struct Qnode{ int w; int po; inline bool operator <(const Qnode &x)const{ return w>x.w; } }; priority_queue<Qnode>q;
|
初始化dis为极大值
1 2
| for(int i = 1;i<=n;i++) dis[i]=2147483647; dis[f]=0;
|
主体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| dis[f]=0; q.push((Qnode){0,f}); while(!q.empty()){ Qnode now =q.top();q.pop(); int u=now.po; if(vis[u]) continue; vis[u]=1; if(road[u].size()){ for(int i = 0;i<=road[u].size()-1;i++){ if(dis[road[u][i].to]>dis[u]+road[u][i].val){ dis[road[u][i].to]=dis[u]+road[u][i].val; pre[road[u][i].to]=u; q.push((Qnode){dis[road[u][i].to],road[u][i].to}); } } } }
|
Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include<iostream> #include<vector> #include<queue> using namespace std; struct node{ int to; int val; }; struct Qnode{ int w; int po; inline bool operator <(const Qnode &x)const{ return w>x.w; } }; priority_queue<Qnode>q; vector <node> road[100004]; int vis[100004],pre[100004]; int dis[100004]; int main(){ int n,m,f,u,v,w; scanf("%d%d%d",&n,&m,&f); for(int i = 1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); road[u].push_back(node{v,w}); } for(int i = 1;i<=n;i++) dis[i]=2147483647; dis[f]=0; q.push((Qnode){0,f}); while(!q.empty()){ Qnode now =q.top();q.pop(); int u=now.po; if(vis[u])continue; vis[u]=1; if(road[u].size()){ for(int i = 0;i<=road[u].size()-1;i++){ if(dis[road[u][i].to]>dis[u]+road[u][i].val){ dis[road[u][i].to]=dis[u]+road[u][i].val; pre[road[u][i].to]=u; q.push((Qnode){dis[road[u][i].to],road[u][i].to}); } } } } for(int i=1;i<=n;i++){ printf("%d ",dis[i]); } return 0; }
|