单源最短路
描述:
给一个
n
(
1
≤
n
≤
2500
)
n(1≤n≤2500)
n(1≤n≤2500)个点
m
(
1
≤
m
≤
6200
)
m(1≤m≤6200)
m(1≤m≤6200)条边的无向图,求
s
s
s到
t
t
t的最短路。
输入:
第一行四个由空格隔开的整数
n
、
m
、
s
、
t
n、m、s、t
n、m、s、t。
之后的 m m m行,每行三个正整数 s i 、 t i 、 w i ( 1 ≤ w i ≤ 1 0 9 ) s_i、t_i、w_i(1≤w_i≤10^9) si、ti、wi(1≤wi≤109),表示一条从 s i s_i si到 t i t_i ti长度为 w i w_i wi的边。
输出:
一个整数表示从
s
s
s到
t
t
t的最短路长度。数据保证至少存在一条道路。
样例输入:
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
样例输出:
7
C++代码实现
#include <iostream>
using namespace std;
int main()
{
int n,m,s,t;
int si,ti,wi;
cin>>n>>m>>s>>t;
int graph[n+1][n+1]; //存储无向图
int a[n]; //最短路径是否已确定
int d[n]; //最短路径长度
for(int i=1;i<=n;i++){ //初始化各辅助表
for(int j=1;j<=n;j++){
if(i==j)
graph[i][j]=0;
else
graph[i][j]=1e9;
}
a[i]=0;
d[i]=1e9;
}
a[s]=1;
d[s]=0;
for(int i=0;i<m;i++){ //读取边的信息并填入图中
cin>>si>>ti>>wi;
if(graph[si][ti]==0 || graph[si][ti]>wi){
graph[si][ti]=wi;
graph[ti][si]=wi;
}
}
int now=s;
int min;
int minpos;
while(a[t]==0){ //s到t的最短路径确定时跳出循环
min=1e9;
minpos=0;
for(int i=1;i<=n;i++)
if(graph[now][i]!=0 && graph[now][i]+d[now]<d[i])
d[i]=graph[now][i]+d[now];
for(int i=1;i<=n;i++)
if(a[i]==0 && d[i]<=min){
min=d[i];
minpos=i;
}
a[minpos]=1; //s到minpos的最短路径已确定
d[minpos]=min;
now=minpos;
}
cout<<d[t]<<endl;
}