首页 > 编程语言 > 详细

Dijkstra算法 (迪杰斯特拉)

时间:2019-09-25 21:51:00      阅读:96      评论:0      收藏:0      [点我收藏+]

定义

  Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

原理

  设图 G=(V,E) 所有顶点的集合为 V,起点为 S,最短路径树中包含的顶点集合为 S。在各计算步骤中,我们将选出最短路径树的边和顶点并将其添加至S。

  对于各顶点 i,设仅经由S内的顶点的 s 到 i 的最短路径成本为 d[i], i 在最短路径树中的父节点为 p[i]。

  ①初始状态下将 S 置空。

      初始化 s 的 d[s]=0;除 s 外,所有属于 V 的顶点 i 的 d[i]=∞。

  ②循环进行下述处理,直至 S=V 为止。

      从 V-S 中选出 d[u] 最小的顶点 u。

     将 u 添加至 S,同时将与 u 相邻且属于 V-S 的所有顶点 v 的值按照下述方式更新

     if(d[u] + w(u,v) < d[v])

        d[v] = d[u] + w(u,v) , p[v] = u ;

  ? 显然迪杰斯特拉算法并不能处理负权图。下图中A->B的最短路应为 3=8-5,但用此算法算出来的A->B的最短路为7。

 技术分享图片

  迪杰斯特拉最短路径算法和普利姆算法贼像。:)

实现

技术分享图片

 

技术分享图片

 

技术分享图片

 

原算法

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
struct node
{
  int v,w;
  node(){}
  node(int a,int b)
  {v=a;w=b;}
};
vector<node> e[maxn];
int n,m;
void dij();
int main()
{
  int i,u,v,w;
  scanf("%d%d",&n,&m);
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d",&u,&v,&w);
    e[u].push_back(node(v,w));
  }
  dij();
  system("pause");
  return 0;
}
void dij()
{
  int dis[maxn],vis[maxn]={0},i,j,mmin,f;
  fill(dis,dis+maxn,inf);
  dis[1]=0;
  for(i=1;i<=n;i++)
  {
    mmin=inf;
    for(j=1;j<=n;j++)
      if(!vis[j]&&dis[j]<mmin)
        mmin=dis[f=j];
    
    vis[f]=1;
    for(j=0;j<e[f].size();j++)
    {
      if(dis[e[f][j].v]>dis[f]+e[f][j].w)
        dis[e[f][j].v]=dis[f]+e[f][j].w;
    }
  }
  for(j=1;j<=n;j++)
    printf("1->%d   %d\n",j,dis[j]);
}

优先队列优化

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
const int inf=0x3f3f3f3f;
struct node
{
  int v,w;
  node(){}
  node(int a,int b)
  {v=a;w=b;}
  bool operator <(const node &n) const
  {return w>n.w;}
};
vector<node> e[maxn];
int n,m;
void dij_queue();
int main()
{
  int i,u,v,w;
  scanf("%d%d",&n,&m);
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d",&u,&v,&w);
    e[u].push_back(node(v,w));
  }
  dij_queue();
  system("pause");
  return 0;
}
void dij_queue()
{
  int dis[maxn],vis[maxn]={0},u,v,w,i;
  node p;
  priority_queue<node> que;
  que.push(node(1,0));
  fill(dis,dis+maxn,inf);
  dis[1]=0;
  while(!que.empty())
  {
    p=que.top();que.pop();
    u=p.v;
    if(vis[u]) continue;
    vis[u]=1;
    for(i=0;i<e[u].size();i++)
    {
     w=e[u][i].w;v=e[u][i].v;
     if(!vis[v]&&dis[v]>dis[u]+w)
      {
        dis[v]=dis[u]+w;
        que.push(node(v,dis[v]));
      }
    }
  }
  for(i=1;i<=n;i++)
    printf("1->%d   %d\n",i,dis[i]);
}

Dijkstra算法 (迪杰斯特拉)

原文:https://www.cnblogs.com/VividBinGo/p/11587673.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!