dijsktra算法
dijsktra是求某个点到所有点的最短距离,即单源最短距离的算法。
(1)找出1所有点中的最短距离,比如说点2离他最近,那么对点2相连的边进行松弛
(2)再找出除了2以外,所有点中离1最近的点,对他们相连的边进行松弛
为什么要每次都找最短的边:因为如果找的不是离1最短的点,可能经过别的点,再到这个点的距离会更短,那么一开始做的后面的更新就无效了。
比如1->2->3可能比1->3更短,如果先从3开始,对和3相连的边进行松弛,那么经过2时候发现3的dis[3]还需要更改,那么和3相连边的松弛操作还要再进行一次。说明前面的松弛毫无意义。
#include<iostream>
#include<algorithm>
#define maxn 100
using namespace std;
int edge[maxn][maxn];//邻接矩阵
int vis[maxn];//标记数组,如果这个点相邻边已经被松弛过,标记为1,下次遍历到的时候跳过
int dis[maxn];//存储1到i这个点现在的距离
void init(int n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
edge[i][j]=0;
else
edge[i][j]=1e9;
}
}
}
void dijkstra(int n)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=edge[1][i];
//找到现在距离1最近的点,一共要找n-1次
for(int i=2;i<=n;i++)
{
int minn=1e9;
int pos=-1;
for(int j=2;j<=n;j++)
{
if(vis[j]==1) continue;//松弛过
if(minn>dis[j])
{
pos=j;
minn=dis[j];
}
}
//标记
vis[pos]=1;
//松弛操作
for(int j=2;j<=n;j++)
{
if(!vis[j]&&edge[pos][j]!=1e9)//这条边存在
{
dis[j]=min(dis[j],dis[pos]+edge[pos][j]);
}
}
}
}
int main()
{
int num;
cin>>num;//几个点
int n;//几条边
cin>>n;
init(n);
//输入边的邻接矩阵
int a,b;//边
for(int i=0;i<n;i++)
{
cin>>a>>b;
cin>>edge[a][b];
//edge[b][a]=edge[a][b];
}
dijkstra(num);
int ans=-1;
for(int i=2;i<=num;i++)
{
ans=max(ans,dis[i]);
}
cout<<ans<<endl;
}