题目描述
给定一张有向图,每条边有一个非负权值。并给出两个点,求这两个点之间最短路的长度。a、b之间的最短路指a出发到b的一条路径,使路径上的边权值之和最小。
输入
第一行包含4个非负整数n、m、a和b,其中n为点数,m为边数,a为起点的编号,b为终点的编号,a, b<n。下面m行,每行3个非负整数,x、y和c,x, y<n,表示一条从x到y的有向边,权值为c。数据保证至少存在一条路径可以从a到b。
输出
输出数据包含一个数,即所求最短路上所有边的权值之和。
样例输入 Copy
5 7 0 4
0 1 1
0 2 2
0 3 5
3 2 15
2 4 25
1 4 17
1 2 0
样例输出 Copy
18
提示
对于80%的数据,n≤1000,m≤10000;
对于100%的数据n≤20000,m≤40000,c≤10000。
对于100%的数据n≤20000,m≤40000,c≤10000。
#include<bits/stdc++.h> using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*f; } const int maxn=5e6+10; int n,m,c; int to[maxn],nxt[maxn],w[maxn]; int head[maxn]; int cnt=1; void add(int x,int y,int z) { to[cnt]=y; w[cnt]=z; nxt[cnt]=head[x]; head[x]=cnt++; } struct node { int x,d; bool operator <(const node& A) const { return d>A.d; } }; bool vis[maxn]; int dis[maxn]; priority_queue<node>q; node tmp; void dijkstra(int s) { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); tmp.x=s,tmp.d=0; q.push(tmp); dis[s]=0; while(!q.empty()) { int x=q.top().x;q.pop(); if(vis[x]) continue; vis[x]=1; for(int i=head[x];i;i=nxt[i]) { int y=to[i]; if(dis[y]>dis[x]+w[i]) { dis[y]=dis[x]+w[i]; tmp.x=y,tmp.d=dis[y]; q.push(tmp); } } } } int qd,zd; void inint(){ n=read(),m=read(); qd=read(),zd=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(),z=read(); add(x,y,z); } } int main() { inint(); dijkstra(qd); printf("%d ",dis[zd]); return 0; }