AC Code:
#include <cstdio>
#include <queue>
using namespace std;
const int mxn=2e9;
int n,m,s,cnt=0;
int first[10005];//记录 一个点 最后的出边 的边编号
int dq[10005],vis[10005];//dp数组 表示从初始点 到当前点的最近距离 vis数组表示哪个节点是否在队列中
struct node{
int back,to,cd;//back是 当前边的 上一条边 to表示当前边的目的节点号,cd表示当前边的长度
}nm[500005];//结构体表示静态邻接表
void addljb(int from,int to,int dis){
nm[++cnt].back=first[from];// 第++cnt 条边的上一条边 等于 以from为起点 上一次 的 出边的编号
nm[cnt].to=to; //当前的边 通往哪个节点
nm[cnt].cd=dis;//当前边的长度
first[from]=cnt; //最后 把 以from为起点的 最后一条出边 赋值给当前 边的编号
}
void spfa(){
queue<int> quq;
for(int i=1;i<=n;i++){
dq[i]=mxn; //带权图初始化
vis[i]=0;//i是否在队列中
}
dq[s]=0;vis[s]=1;quq.push(s);
while(!quq.empty()){
int qwq=quq.front();//取出队首
quq.pop();vis[qwq]=0;//出队标记
//遍历qwq为起点的所有出边
for(int i=first[qwq];i;i=nm[i].back){//遍历 静态邻接表 ,以qwq为起点的最后一条边,开始
int bian=nm[i].to;
if(dq[bian]>dq[qwq]+nm[i].cd){//如果有最短路就更改
dq[bian]=dq[qwq]+nm[i].cd;
if(!vis[bian]){//未入队则入队
vis[bian]=1;//标记入队
quq.push(bian);
}
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&s);
int f,g,w;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&f,&g,&w);
addljb(f,g,w);//建图,有向图连一次边就可以了
}
spfa();
for(int i=1;i<=n;i++){
if(dq[i]==mxn)printf("2147483647 ");
else printf("%d ",dq[i]);
}
return 0;
}
P3371 【模板】单源最短路径(弱化版)
2019-05-10