题目:给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式:第一行包含三个整数 n,m,s,分别表示点的个数、有向边的个数、出发点的编号。
接下来 m行每行包含三个整数 u,v,w,表示一条 u→v 的,长度为 w 的边。
输出格式:输出一行 n 个整数,第 i 个表示 s 到第 i个点的最短路径,若不能到达则输出 2^{31}−1。
//单源最短路算法——Dijkstra
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct edge//前向星存边 ,固定写法
{
int j;//该边的子节点
int l;//该边的权值
int h;//与它最近的父节点一样的边的编号
}bian[500005];
int head[500005];//以某点为父节点引出的最后一条边
int cnt;//边编号
inline void add(int u,int v, int val)//存边 ,固定写法
{
cnt++;
bian[cnt].j=v;
bian[cnt].l=val;
bian[cnt].h=head[u];
head[u]=cnt;
}
int main()
{
bool visit[10005]={0}; //是否作为过起点
long long dis[10005];//距离
int n,m,s;
int a,b,c;
cin>>n>>m>>s;//输入点个数,边个数,起点的编号
for(int i=1;i<=n;i++)
dis[i]=2147483647;//2147483647为最大数
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;//输入a为起点,b为终点,c为权值
add(a,b,c);
}
int curr=s;//起点
dis[s]=0; //起点的赋值为0
long long minn;
while (!visit[curr])
{
visit[curr]=true;
for(int i=head[curr];i!=0;i=bian[i].h)//链式前向星搜边
{
if(!visit[bian[i].j]&&dis[bian[i].j]>dis[curr]+bian[i].l)
dis[bian[i].j]=dis[curr]+bian[i].l;
}
minn=2147483647;
for(int i=1;i<=n;i++)
{
if(!visit[i]&&minn>dis[i])
{
minn=dis[i];
curr=i;
}
}
}
for(int i=1;i<=n;i++)
cout<<dis[i]<<" ";
return 0;
}