dijsktra算法

dijsktra算法

dijsktra是求某个点到所有点的最短距离,即单源最短距离的算法。

(1)找出1所有点中的最短距离,比如说点2离他最近,那么对点2相连的边进行松弛
(2)再找出除了2以外,所有点中离1最近的点,对他们相连的边进行松弛

为什么要每次都找最短的边:因为如果找的不是离1最短的点,可能经过别的点,再到这个点的距离会更短,那么一开始做的后面的更新就无效了。
比如1->2->3可能比1->3更短,如果先从3开始,对和3相连的边进行松弛,那么经过2时候发现3的dis[3]还需要更改,那么和3相连边的松弛操作还要再进行一次。说明前面的松弛毫无意义。


#include
#include
#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;
}


你可能感兴趣的:(dijsktra算法)