题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式
第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。
接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。
输出格式
一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)
输入
4 6 1 1 2 2 2 3 2 2 4 1 1 3 5 3 4 3 1 4 4
输出
0 2 4 3
1 #include<bits/stdc++.h> 2 using namespace std; 3 const long long inf=0x3f3f3f3f; 4 long long n,m,s; 5 long long first[500009],next[500009],to[500009],w[500009],tot; 6 long long dis[500009]; 7 bool book[500009]; 8 struct node{ 9 long long val,num; 10 bool operator <(const node &a)const 11 { 12 return a.val<val; 13 } 14 }; 15 priority_queue<node>q; 16 void add_edge(long long a,long long b,long long c) 17 { 18 next[++tot]=first[a]; 19 first[a]=tot; 20 to[tot]=b; 21 w[tot]=c; 22 } 23 inline int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 27 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 28 return x*f; 29 } 30 int main(){ 31 cin>>n>>m>>s;//输入 32 for(int i=1;i<=m;i++) 33 { 34 long long a=read(),b=read(),c=read(); 35 add_edge(a,b,c);//添加有向图的边 36 } 37 for(int i=1;i<=n;i++)dis[i]=inf;//先将dis设为无限大 38 node fir; 39 fir.val=0,fir.num=s; 40 dis[s]=0; 41 q.push(fir);//离起点最短的第一个入队 42 while(q.empty()==false)//每次从离起点最近的点开始走 43 { 44 long long u=q.top().num;//获取堆顶的标号 45 q.pop();//弹出 46 if(book[u]==true)continue;//已经在堆中出现过了,就跳过 47 book[u]=true; 48 for(int i=first[u];i;i=next[i])//遍历每一条与它相连的边 49 { 50 long long v=to[i];//这条边的终点 51 if(dis[u]+w[i]<dis[v])//如果它现在的最短距离大于起点的最短距离加上起点到终点的距离 52 { 53 dis[v]=dis[u]+w[i];//更新距离 54 node xia; 55 xia.val=dis[v]; 56 xia.num=v; 57 if(book[v]==false)q.push(xia);//还没入过堆就压进去 58 } 59 } 60 } 61 for(int i=1;i<=n;i++)printf("%lld ",dis[i]); 62 }