zoukankan      html  css  js  c++  java
  • Dijkstra算法O (N2)

    用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法。也就是说,只能计算起点只有一个的情况
    Dijkstra的时间复杂度是O (N2),它不能处理存在负边权的情况
    算法描述:
           设起点为sdis[v]表示从sv的最短路径,pre[v]v的前驱节点,用来输出路径。
           a)初始化:dis[v]=(vs); dis[s]=0; pre[s]=0;
           b)For (i = 1; i <= n ; i++)
                1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的。
                2.u标记为已确定最短路径
                3.For u相连的每个未确定最短路径的顶点v
                  if  (dis[u]+w[u][v]<dis[v])
                   {
                      dis[v]=dis[u]+w[u][v];
                      pre[v]=u;
                   }
            c)算法结束:dis[v]sv的最短距离;pre[v]v的前驱节点,用来输出路径。
    算法实现步骤:
        设图G用邻接矩阵的方式存储在GA中,GA[I,j]=maxint表示vi,vj是不关联的,否则为权值(大于0的实数)。设集合s用来保存已求得的最短路径的终点序号,初始时s=[vi]表示只有源点,以后每求出一个终点vj就把它加入到集合中并作为新考虑的中间结点。
        设数组dist[1..n]用来存储当前求得的最短路径,初始时vi,vj如果是关联的,则dist[j]=权值,否则=maxint,以后,随着考虑的中间结点越来越多,dist[j]可能越来越小。再设一个与dist数组相对应的数组path[1..n],用path[j]来存放当前vi-vj的最短路径上vj点的前驱,初始时为vi的边,如果不存在边,则为0。
        执行时,先从s以外的顶点(即待求出最短路径的终点)所对应的dist数组元素中,找出其值最小的元素(假设为dist[m]),该元素的值就是从源点vi到终点vm的最短路径长度,从对应的path[m]中的顶点开始递归直到源点的序列即为最短路径。接着把vm并入集合s中,然后以vm作为新考虑的中间结点,对s以外的每个顶点vj,比较dist[m]+GA[m,j]和dist[j]的大小,若前者小,表明加入中间结点后可以得到更好的方案,即可求得更短的路径,那么就用dist[m]+GA[m,j]替代原来的dist[j],同时把vm存入到path[j]中。重复以上n-2次,即可在dist数组得到从源点到其余各终点的最短路径长度,对应的path数组中保存着相应的最短路径的终点前驱。
    算法执行过程图示分析:
      
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int map[1000][1000];
     6 int vis[1000];
     7 int dis[1000];
     8 int path[1000];
     9 int n,m,w;
    10 int e;
    11 const int maxn=999999;
    12 void df(int);
    13 void print(int, int);
    14 int main()
    15 {
    16     cin>>n>>m;
    17     memset(dis,maxn,sizeof(dis));
    18     memset(map,maxn,sizeof(map));
    19     for(int i=1;i<=m;i++)
    20      {
    21          int x,y;
    22          cin>>x>>y>>w;
    23          map[x][y]=map[y][x]=w;
    24      }
    25     memset(vis,0,sizeof(vis));
    26     int a;
    27     cin>>a>>e;
    28     df(a);
    29     print(a,e);
    30 } 
    31 void df(int s)
    32 {
    33     for(int i=1;i<=n;i++)
    34      {
    35          dis[i]=map[s][i];
    36          if(dis[i]!=maxn)
    37           {
    38               path[i]=s;
    39           }
    40         else path[i]=0;
    41      }
    42      vis[s]=1;
    43      dis[s]=0;
    44      int k,min1;
    45      for(int i=1;i<=n-1;i++)
    46       {
    47           k=s;
    48           min1=maxn;
    49           for(int j=1;j<=n;j++)
    50            {
    51                if(dis[i]<min1&&vis[j]==0)
    52                 {
    53                     min1=dis[i];
    54                     k=j;
    55                 }
    56            }
    57            vis[k]=1;
    58            for(int q=1;q<=n;q++)
    59             {
    60                 if(vis[q]==0&&dis[q]>dis[k]+map[k][q])
    61                  {
    62                      dis[q]=dis[k]+map[k][q];
    63                      path[q]=k;
    64                  }
    65             }
    66       }
    67       cout<<dis[e]<<" ";
    68 }
    69 void print(int u,int r)
    70 {
    71     int que[1000];
    72     int tot=1;
    73     int temp;
    74     que[tot]=r;
    75     tot++;
    76     temp=path[r];
    77     while(temp!=u)
    78      {
    79          que[tot]=temp;
    80          tot++;
    81          temp=path[temp];
    82      }
    83      que[tot]=u;
    84      for(int i=tot;i>=1;i--)
    85       {
    86           cout<<que[i]<<"-->"; 
    87       }
    88 }
                 
                 
                 
  • 相关阅读:
    DOM
    笔试题
    小案例
    前端基础面试题
    2048小游戏
    JS原型与构造函数
    String字符串和正则表达式
    数组
    MySQL_PHP学习笔记_2015_0906_使用PHP模板
    MySQL_PHP学习笔记_2015_0614_PHP传参总结_URL传参_表单传参
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/6686067.html
Copyright © 2011-2022 走看看