题目描述:
blablablablablablablablablabla 传送门
算法思想:
由题可知,此题为稠密图,所以用邻接矩阵来存,下面是代码中几个变量的含义:
dist[i]
表示由起点到i
点的最短距离
g[i][j]
存图,表示从i
点到j
点的直接距离(不经过松弛操作的距离)
st[i]
表示i
位置的点的最短距离是否已经确定
n,m
节点数和边数
下面是具体步骤:
- 在最短路未确定的点中,找距离源点最近的点
t
- 用
t
更新其他点的距离(松弛操作)
注意事项:
- 存图之前,现将
g
数据初始化为无限大,因为可能会有重边,输入的时候取最小边就行 - 还要将
dist
初始化成无限大,如果经过更新后仍为无限大,输出-1
即可
时间复杂度:
O ( n 2 + m ) , n 表 示 点 数 , m 表 示 边 数 O(n^2+m), n 表示点数,m 表示边数 O(n2+m),n表示点数,m表示边数
代码实现:
#include <iostream>
#include <cstring>
using namespace std;
const int N=505;
int n,m;
int g[N][N],st[N],dist[N*N];
int di()
{
memset(dist,0x3f,sizeof(dist));
dist[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!st[j] && (t==-1 || dist[t]>=dist[j])) t=j;
}
for(int j=1;j<=n;j++)
{
if(dist[j]>dist[t]+g[t][j])
{
dist[j]=dist[t]+g[t][j];
}
}
st[t]=1;
}
if(dist[n]==0x3f3f3f3f) return -1;
else return dist[n];
}
int main ()
{
memset(g,0x3f,sizeof(g));
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);
}
cout<<di();
return 0;
}