https://www.luogu.org/problem/P4779落谷上的一个模板题目
题目背景
2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。
然后呢?
100 \rightarrow 60100→60;
Ag \rightarrow CuAg→Cu;
最终,他因此没能与理想的大学达成契约。
小 F 衷心祝愿大家不再重蹈覆辙。
题目描述
给定一个 NN 个点,MM 条有向边的带非负权图,请你计算从 SS 出发,到每个点的距离。
数据保证你能从 SS 出发到任意点。
输入格式
第一行为三个正整数 N, M, SN,M,S。 第二行起 MM 行,每行三个非负整数 u_i, v_i, w_iui,vi,wi,表示从 u_iui 到 v_ivi 有一条权值为 w_iwi 的边。
输出格式
输出一行 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
这个题目wa了好多发。。。原因就是没有深入的理解队列的含义!!唉~~
#include<iostream> #include<cstdio> #include<vector> #include<queue> #include<cstring> using namespace std; const int N=1E5+7; const int INF=0x3f3f3f3f; typedef long long ll; struct stu{ ll a,b; }; ll dis[N]; int mark[N]; vector<stu>ve[N]; struct node{ int x,y; bool friend operator<(const node x1,const node y1){ return x1.y>y1.y; } }; void djstrea(int s){ memset(mark,0,sizeof(mark)); memset(dis,INF,sizeof(dis)); priority_queue<node>que; dis[s]=0; que.push({s,0}); while(que.size()){ node xx=que.top(); que.pop(); if(mark[xx.x]==1) continue ; mark[xx.x]=1; for(int i=0;i<ve[xx.x].size();i++){ int dx=ve[xx.x][i].a; int dy=ve[xx.x][i].b; if(mark[dx]==0&&dis[dx]>dis[xx.x]+dy){ dis[dx]=dis[xx.x]+dy; if(mark[dx]==0) que.push({dx,dis[dx]}); } } } } int main(){ int n,m,s; cin>>n>>m>>s; int x,y,z; for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); ve[x].push_back({y,z}); // ve[y].push_back({x,z});//单向能过。双向应该也可以的 } djstrea(s); for(int i=1;i<=n;i++) cout<<dis[i]<<" "; return 0; }