B类 洛谷 P4779
题意:
给定一个 NNN 个点,MMM 条有向边的带非负权图,请你计算从 SSS 出发,到每个点的距离。
数据保证你能从 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
求从1到其他所有点的最短距离,用dijkstra做
最基本模板
代码:
#include<bits/stdc++.h> using namespace std; #define maxn 100010 #define maxm 500010 #define INF 0x7fffffff int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn]; struct Edge{ int u,v,w,next; }edge[maxm]; struct node{ //堆节点 int w,pos; bool operator<(const node &x)const{ return w>x.w; } }; priority_queue<node>q; //堆 inline void add(int u,int v,int w){ //链式前向星 edge[++cnt].u=u; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt; } void dijkstra(){ for(int i=1;i<=n;i++){ dis[i]=INF; } dis[s]=0; // 赋初值 s到s的距离为0 q.push((node){0,s}); // 把源点扔进堆里 while(!q.empty()){ node x=q.top(); // 取堆顶 q.pop(); // 弹堆 int u=x.pos; if(vis[u]) continue; vis[u]=1; for(int i=head[u];i;i=edge[i].next){ int v=edge[i].v; if(dis[v]>dis[u]+edge[i].w){ dis[v]=dis[u]+edge[i].w; // 松弛操作 if(!vis[v]){ q.push((node){dis[v],v}); } } } } } int main(){ scanf("%d%d%d",&n,&m,&s); for(int i=1,x,y,z;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); // 加单向边 } dijkstra(); for(int i=1;i<=n;i++){ printf("%d ",dis[i]); } return 0; }