精华内容
下载资源
问答
  • ![图片说明]...如图,怎样求的从节点A到节点Y的最短路径?当然不能每步都选权值最小的,因为比如节点M就到不了节点Y嘛。那应该用什么方法呢?广度优先遍历?
  • 借助ACM1242题深入理解迷宫类最短路径搜索并记录路径长度的问题及解决方法;这是初次接触优先队列,尤其是不知道该怎样去记忆在结构体重自定义大小比较的符号方向,很容易混淆符号向哪是从大到小排列,向哪是从小到...

    借助ACM1242题深入理解迷宫类最短路径搜索并记录路径长度的问题及解决方法;
    这是初次接触优先队列,尤其是不知道该怎样去记忆在结构体重自定义大小比较的符号方向,很容易混淆符号向哪是从大到小排列,向哪是从小到大排列;
    这非常向sort和qsort排序。

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1242

     1 #include<iostream>
     2 #include<cstring>
     3 #include<queue>
     4 using namespace std;
     5 const int N=1000;
     6 char map[N][N];
     7 int vis[N][N];
     8 struct Node
     9 {
    10     int x,y,step;
    11     friend bool operator<(Node v,Node u)
    12     {
    13         return v.step>u.step;//怎么记啊 
    14     }
    15 }XX;
    16 int n,m; 
    17 int direction[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    18 bool Check(int x,int y)
    19 {
    20     if(x<0||y<0||x>=n||y>=m||map[x][y]=='#'||!vis[x][y])
    21     return false;
    22     return true;
    23 }
    24 int dfs(Node S,Node E)
    25 {
    26     priority_queue<Node>Q;
    27     S.step=0;
    28     Q.push(S);
    29     Node temp;
    30     vis[S.x][S.y]=0;
    31     while(!Q.empty())
    32     {
    33         Node mid;
    34         mid=Q.top();
    35         Q.pop();
    36         if(mid.x==E.x&&mid.y==E.y)return mid.step;
    37         for(int i=0;i<4;i++) 
    38         {    
    39             Node next=mid;
    40             next.x=mid.x+direction[i][0];
    41             next.y=mid.y+direction[i][1];
    42             if(Check(next.x,next.y))
    43             {
    44             next.step++;
    45             if(map[next.x][next.y]=='x')
    46             next.step++;
    47             if(vis[next.x][next.y]>next.step)//其实这步可以抛弃,只是增大下面优先队列的处理数据量
    48             {
    49                 vis[next.x][next.y]=next.step;//其实也可以没有这一步
    50                 Q.push(next);
    51     
    52             }
    53             }
    54         }
    55     }
    56     return -1;//返回它时说明无法到达目的地
    57 }
    58 int main()
    59 {
    60     while(cin>>n>>m)
    61     {
    62         memset(vis,1,sizeof(vis));//这里用的memset将vis赋特别大的值 ;
    63         //memset一般用于赋值是-1和零,也用于char型符号赋值,但是当赋值为其他int型整数时,
    64         //所得到的结果并不是你所写上的数,就像上面写的1,其实结果是很大的数,可以输出试验下; 
    65         Node s;//起点位置 
    66         Node e;//终点位置 
    67         for(int i=0;i<n;i++)
    68     {
    69         cin>>map[i];
    70         for(int j=0;j<m;j++)
    71         if(map[i][j]=='a')
    72         {
    73             e.x=i;e.y=j;
    74         }
    75         else if(map[i][j]=='r')
    76         {
    77             s.x=i;
    78             s.y=j;
    79         }
    80         else if(map[i][j]=='x')//是保存那个特出守卫的坐标的 
    81         {
    82             XX.x=i;XX.y=j;
    83         }
    84     }
    85     int time=dfs(s,e);
    86     if(time==-1)cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
    87     else cout<<time<<endl;
    88     }
    89 }

    做这个题目话费了我好长好长时间,现在也不是太懂,不过还好啦,最起码理解这种方法了;算是长能力了。哈哈哈!

    转载于:https://www.cnblogs.com/sytu/p/3843542.html

    展开全文
  • 我使用spark的graphx图计算框架,现在要求一个图中所有节点对的最短路径条数, graphx下的pregel迭代貌似使用的是类迪杰斯特拉算法,要求最短路径长度很容易, 但是要求条数,我实在是想不出来怎么,希望各位大神...
  • 图论(1)、最短路径

    2018-03-15 18:00:38
    说道图,最先想到也是最常用的,自然就是怎样求最短路径。我们常说的最短路径指的是单源最短路径。常见的解决单源最短路径问题的算法有Dijkstra算法和Bellman-Ford算法。这两种算法都是基于动态规划思想实现的,所以...

    图论是离散数学中比较重要的一个分支;而图,恰好又是计算机中最重要的数据结构。所以今天开一个图论专题。



    说道图,最先想到也是最常用的,自然就是怎样求最短路径。我们常说的最短路径指的是单源最短路径。常见的解决单源最短路径问题的算法有Dijkstra算法和Bellman-Ford算法。这两种算法都是基于动态规划思想实现的,所以这两个算法都有一个核心操作,就是松弛(Relax)。但是它们适用的范围不太一样。而对于多源最短路径,则有Floyd算法实现。


    迪杰斯特拉算法

    朴素Dijkstra算法遍历某一结点到其他结点的最短路径,其特点类似于BFS,层层向外扩展,直到找到终点为止。这种方法实现起来十分好理解,但是由于它遍历了大量的结点,导致它的时间复杂度达到了O(V^2+E)。若源点可达,复杂度变成O(V*logV+E*logV)。在稀疏图上,由于E=V*V/logV,时间复杂度可达O(V^2)。我们可以考虑用heap去优化Dijkstra,这样能使得复杂度进一步降低,获得O(VlogV+E)。

    贝尔曼-福特算法


    Dijkstra算法有个局限性,就是它只能求解单源、正权的最短路径。一旦图上含负权,Dijkstra就无能为力了。原因很好理解,Dijkstra在贪心地寻找当前距源点最小距离的点时,有可能先走过次优点,再走过该负权,会使得最短距离更小。反例很好举,大家随便举一下就可以了。那么含有负权的最短路径怎么解决呢?采用Bellman-Ford算法就可以了。Bellman算法的核心和Dijkstra一样,就是松弛操作。但是Bellman反复用已有的边去更新最短距离,对于当前结点v,一旦发现dis[v]>dis[u]+graph[u][v],就要把dis[v]维护为dis[u]+graph[u][v]。并且Bellman还有一个功能,就是判负环,如果没有负环的话,该算法会在n-1次维护后结束。该算法的时间复杂度来到了O(V*E)。


    最短路快速算法

    SPFA(Shortest Path Fastest Algorithm)实际上是对于Bellman的一种优化。它使用了队列这种数据结构,保存结点信息。当一个结点被更新之后,没有必要立即去更新其他结点,这样复杂度就会降低为O(k*E)(k是远小于V的一个常数,通常小于2)。但是SPFA是一个不稳定的算法,在稀疏图的情况下,它的表现十分优异;但是在稠密图下,它就退化成了Bellman-Ford算法。它当然也可以加堆优化,在c++中则可以使用STL中的priority_queue实现。



    关于这三种算法的选择,还是要根据实际问题考虑。在一般问题中,不太可能出现负权图,所以我们使用最稳定的Dijkstra,一旦出现负权了,我们就可以考虑SPFA了。这儿有一个小的事项,就是存图方法。

    常见的存图方法有三种:邻接矩阵、邻接表、链式前向星。Bellman是可以用边集数组实现的,而SPFA一般来说用的都是链式前向星。关于链式前向星这种存图方法,http://blog.csdn.net/acdreamers/article/details/16902023  这个博客的说明可以借鉴一下。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn=1e5+7;
    int len[maxn];
    int head[maxn];
    bool vis[maxn];
    ll dis[maxn];
    int index,m,n;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    struct edge{
        int next;
        int to;
        int w;
    }edge[maxn];
    
    void init(){
        index=1;
        memset(head,0,sizeof(head));
    }
    
    void add(int u,int v,int w){
        edge[index].w=w;
        edge[index].to=v;
        edge[index].next=head[u];
        head[u]=index++;
    }
    
    void visit(int sta){
        queue<int>q;
        memset(vis,0,sizeof(vis));
        memset(dis,INF,sizeof(dis));
        q.push(sta);
        vis[sta]=1;
        dis[sta]=0;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            vis[now]=0;
            for(int i=head[now];i;i=edge[i].next){
                int w=edge[i].w;
                int son=edge[i].to;
                printf("%d --> %d  , weight = %d\n",now,edge[i].to,edge[i].w);
                if(dis[now]+w<dis[son]){
                    dis[son]=dis[now]+w;
                    if(!vis[son]){
                        q.push(son);
                        vis[son]=1;
                    }
                }
            }
        }
        puts("/********************************* Weight *************************************/");
        for(int i=1;i<=n;++i){
            if(dis[i]!=INF)
            printf("%d --> %d shortest distance is %d\n",sta,i,dis[i]);
        else
            printf("%d --> %d shortest distance is Infinite\n",sta,i);
        }
        puts("/******************************** Distance ***********************************/");
    }
    
    int main(){
        while(1){
            init();
            scanf("%d",&n);
            scanf("%d",&m);
            while(m--){
                int s,e,w;
                scanf("%d%d%d",&s,&e,&w);
                add(s,e,w);
            }
            int start_point;
            for(start_point=1;start_point<=n;start_point++)
            visit(start_point);
            for(int i=1;i<n;i++)
                cout<<head[i]<<" ";
        }
    
        return 0;
    }
    

    展开全文
  • 前面我们已经了解到了无环有向图怎样求关键路径的方法,今天我们来看看无向图怎样求最短路径,这在实际应用过程中的作用很大,不如交通路线图,从出发点到终点,走哪条路用时最短,或者花费最少等问题。 我们先来看...

    前面我们已经了解到了无环有向图怎样求关键路径的方法,今天我们来看看无向图怎样求最短路径,这在实际应用过程中的作用很大,不如交通路线图,从出发点到终点,走哪条路用时最短,或者花费最少等问题。

    我们先来看单源最短路径的求法。即给定了起点vv,求从起点出发,到图中各个顶点的最短路径问题。
    对于这个问题,迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的次序产生的最短路径的算法。

    下面介绍迪杰斯特拉算法思想:
    (1)、假设用带权的邻接矩阵arcs来表示带权有向图,arcs[i][j]表示弧<viv_i,vjv_j>上的权值。若<viv_i,vjv_j>不存在,则置arcs[i][j]为无穷大(在计算机中可用允许的最大值代替。)S为已经找到的从vv出发的最短路径的终点的集合,他的初始状态为空集。那么,从v出发到图中的其余各顶点(终点)viv_i可能达到的最短路径长度的初值为:
    D[i] = arcs[ Locate Vex(G,v) ][i] viv_i 属于 V
    (2)、选择vjv_j,使得:D[j] = Min{D[i] | viv_i 属于 V-S},vjv_j就是当前求得的一条从v出发的最短路径的终点。令:S = S 并 {j}
    (3)、修改从v出发到集合V-S上任意一点vkv_k可达的最短路径长度。如果:D[j] + arcs[k][k] < D[k],则修改D[k]为:D[k]= D[j] + arcs[j][k]
    (4)、重复操作(2)、(3)共n-1次。由此求得从v到图上其余各顶点的最短路径是依据路径长度递增的序列。

    太复杂了,我们来总结描述下:
    迪杰斯特拉算法:
    假设存在G=<V,E>,源顶点为V0,S={V0},distance[i] 记录V0到i的最短距离,matrix[i][j]记录从i到j的边的权值,即两点之间的距离。
    1)从V-S中选择使dist[i]值最小的顶点i,将i加入到U中;
    2)更新与i直接相邻顶点的dist值。dist[j]=min{dist[j],dist[i]+matrix[i][j]}
    3)直到S=V,所有顶点都包含进来了,算法停止。

    Dijkstra算法主要针对的是有向图的单源最短路径问题,且不能出现权值为负的情况!Dijkstra算法类似于贪心算法,其应用根本在于最短路径的最优子结构性质。

    最短路径的最优子结构性质:
    如果P(i,j)={Vi…Vk…Vs…Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。

    根据其算法思想,确立操作步骤如下:
    (1) 初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为"起点s到该顶点的距离"[例如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。
    (2) 从U中选出"距离最短的顶点k",并将顶点k加入到S中;同时,从U中移除顶点k。
    (3) 更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。
    (4) 重复步骤(2)和(3),直到遍历完所有顶点。

    下面我们用列表法来手动实现这个过程:
    我们以下图为例:起点为A
    在这里插入图片描述
    1、找到起始点A,找出从A到图中各点的路径长度:A的邻接点未B和D,其余点距离都为inf(无穷大)
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 max 2 max max

    2、找到最小值是从A到B的距离1,接下来以B为起始点,找到B的邻接点D,C,E:
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 inf 2 inf inf
    2 【1】 min{1+2,inf}=3 min{1+4,2}=2 min{1+3,inf}=4 inf

    3、找到第二次最小值为从A到D的距离2,以D为起始点:
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 inf 2 inf inf
    2 【1】 min{1+2,inf}=3 min{1+4,2}=2 min{1+3,inf}=4 inf
    3 【1】 3 【2】 min{2+6,4,inf}=4 inf

    4、找到第三次的最小值从A到C的值3,以C为起始点:
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 inf 2 inf inf
    2 【1】 min{1+2,inf}=3 min{1+4,2}=2 min{1+3,inf}=4 inf
    3 【1】 3 【2】 min{2+6,4,inf}=4 inf
    4 【1】 【3】 【2】 min{3+1,4,inf}=4 min{3+4,inf}=7

    5、找到第4次最小值是从A到E的值4,以E为起始点:
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 inf 2 inf inf
    2 【1】 min{1+2,inf}=3 min{1+4,2}=2 min{1+3,inf}=4 inf
    3 【1】 3 【2】 min{2+6,4,inf}=4 inf
    4 【1】 【3】 【2】 min{3+1,4,inf}=4 min{3+4,inf}=7
    5 【1】 【3】 【2】 【4】 min{4+2,7,inf} =6

    至此所有的顶点全部遍历完成:
    在这里插入图片描述

    次数/编号 B C D E F
    1 1 inf 2 inf inf
    2 【1】 min{1+2,inf}=3 min{1+4,2}=2 min{1+3,inf}=4 inf
    3 【1】 3 【2】 min{2+6,4,inf}=4 inf
    4 【1】 【3】 【2】 min{3+1,4,inf}=4 min{3+4,inf}=7
    5 【1】 【3】 【2】 【4】 【6】

    那么从表中我们就能够得到:
    A到B,到C,到D,到E,到F的最短路径依次为1,3,2,4,6

    现在我们得到了从A到各个节点的最短路径的值,那么问题来了,怎样得到最短路径呢?

    例如,现在我们要求出从A到F的最短路径:
    我们使用上一跳存储列表法来实现,初始化都为-1,-1表示直连。

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top -1 -1 -1 -1 -1

    1、首先是顶点B,因为B和A直连,所以,直接赋值为-1

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top 【-1】 -1 -1 -1 -1

    2、接下来是顶点C,A要到达顶点C,距离为3,必须经过顶点B,所以C的上一跳为B

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top 【-1】 B -1 -1 -1

    3、接下来是点D,D和A直连,直接赋值为-1

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top 【-1】 B 【-1】 -1 -1

    4、接下来是点E,A要到达E,距离为4,必须经过顶点B,所以E的上一跳为B

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top 【-1】 B 【-1】 B -1

    5、接下来是点F,A要到达顶点F,距离为6,必须经过顶点E,所以F的上一跳为E

    名称/编号 B C D E F
    cost 1 3 2 4 6
    last—top 【-1】 B 【-1】 B E

    那么现在我们要从A到F,最短路径是什么呢?
    过程是这样的要到F,得经过E;要到E,得经过B;要到B,得经过A。
    于是,从A到F的最短路径为:A —> B —> E —> F

    def Dijkstra(network, s, d):  # 迪杰斯特拉算法算s-d的最短路径,并返回该路径和值
        print("Start Dijstra Path……")
        path = []  # 用来存储s-d的最短路径
        n = len(network)  # 邻接矩阵维度,即节点个数
        fmax = float('inf')
        w = [[0 for _ in range(n)] for j in range(n)]  # 邻接矩阵转化成维度矩阵,即0→max
    
        book = [0 for _ in range(n)]  # 是否已经是最小的标记列表
        dis = [fmax for i in range(n)]  # s到其他节点的最小距离
        book[s - 1] = 1  # 节点编号从1开始,列表序号从0开始
        midpath = [-1 for i in range(n)]  # 上一跳列表
        for i in range(n):
          for j in range(n):
            if network[i][j] != 0:
              w[i][j] = network[i][j]  # 0→max
            else:
              w[i][j] = fmax
            if i == s - 1 and network[i][j] != 0:  # 直连的节点最小距离就是network[i][j]
              dis[j] = network[i][j]
        for i in range(n - 1):  # n-1次遍历,除了s节点
          min = fmax
          for j in range(n):
            if book[j] == 0 and dis[j] < min:  # 如果未遍历且距离最小
              min = dis[j]
              u = j
          book[u] = 1
          for v in range(n):  # u直连的节点遍历一遍
            if dis[v] > dis[u] + w[u][v]:
              dis[v] = dis[u] + w[u][v]
              midpath[v] = u + 1  # 上一跳更新
        j = d - 1  # j是序号
        path.append(d)  # 因为存储的是上一跳,所以先加入目的节点d,最后倒置
        while (midpath[j] != -1):
          path.append(midpath[j])
          j = midpath[j] - 1
        path.append(s)
        path.reverse()  # 倒置列表
        print("path:",path)
        # print(midpath)
        print("dis:",dis)
        # return path
    
    network = [[0, 1, 0, 2, 0, 0],
               [1, 0, 2, 4, 3, 0],
               [0, 2, 0, 0, 1, 4],
               [2, 4, 0, 0, 6, 0],
               [0, 3, 1, 6, 0, 2],
               [0, 0, 4, 0, 2, 0]]
    Dijkstra(network, 1, 6)
    

    运行结果:

    Start Dijstra Path……
    path: [1, 2, 5, 6]
    dis: [2, 1, 3, 2, 4, 6]
    
    展开全文
  • 课堂笔记:最短路径

    2019-12-01 16:23:18
    在非网图中,最短路径是指两顶点之间经历的边数最少的路径。...问题描述:给定带权有向图G=(V, E)和源点v∈V,从v到G中其余各顶点的最短路径。 应用实例——计算机网络传输的问题:怎样找到一种最...

    非网图中,最短路径是指两顶点之间经历的边数最少的路径
    网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径
    单源点到其他顶点的最短路径:Dijkstra方法,O(n2)
    任意一对顶点之间的最短路径:Floyed方法,O(n3)
    单源点最短路径问题
    问题描述:给定带权有向图G=(V, E)和源点v∈V,求从v到G中其余各顶点的最短路径。
    应用实例——计算机网络传输的问题:怎样找到一种最经济的方式,从一台计算机向网上所有其它计算机发送一条消息。
    迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的次序产生最短路径的算法——Dijkstra算法。
    路径长度递增的理解
    含有n个顶点的图,计算图中顶点v到其他顶点(n-1个)的最短路,总共要找n-1条最短路。
    按路径长度递增指的是这n-1条路的计算原则即, 先找第一条最短路(v,vi),所有n-1条路中最短的路,再找第二条最短路(v,vj)…
    Dijkstra算法
    基本思想:

    1、设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
    2、对vi∈V-S,假设从源点v到vi的有向边为最短路径(从v到其余顶点的最短路径的初值)。
    3、以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。
    重复上述过程,直到集合V中全部顶点加入到集合S中。
    路径长度最短的最短路径(即第一条最短路)的特点
    在这条路径上,必定只含一条边,并且这条边上的权值最小。
    下一条路径长度次短的最短路径的特点
    它只可能有两种情况: 或者是直接从源点到该点(只含一条边); 或者是从源点经过顶点v1(第一条最短路径所依附的顶点),再到达该顶点(由两条边组成)。
    再下一条路径长度次短的最短路径的特点:
    它可能有四种情况:或者是直接从源点到该点(只含一条边); 或者从源点经过顶点v1,再到达该顶点(由两条边组成);或者是从源点经过顶点v2,再到达该顶点(两条条边);或者是从源点经过顶点v1、v2,再到达该顶点(多条边)。
    其余最短路径的特点
    它或者是直接从源点到该点(只含一条边); 或者是从源点经过已求得最短路径的顶点(集合S中的顶点),再到达该顶点。
    正确性证明
    下一条最短路径或者是弧(v0,vx),或者是中间经过S中的某些顶点而后到达vx的路径。 
    用反证法: 假设下一条最短路径上有一个顶点vy不在S中, 即此路径为(v0,…,vy,…,vx)。 显然,(v0,…,vy)的长度小于(v0,…,vy,…,vx)的长度, 故下一条最短路径应为(v0,…,vy), 这与假设的下一条最短路径(v0,…,vy,…, vx)相矛盾! 因此,下一条最短路径上不可能有不在S中的顶点vy,即假设不成立。
    数据结构 :
    图的存储结构:邻接矩阵存储结构
    数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长度。初态为: 若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
    数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
    数组s[n]:存放源点和已经找到最短路径的终点,其初态为只有一个源点v。
    迪杰斯特拉算法的主要步骤如下
    (1) g为用邻接矩阵表示的带权图。 S←{v0} , dist[i]=g.arcs[v0][vi],path[i]=“v0vi”或“”;将v0到其余顶点的路径长度初始化为权值;
    (2) 选择vk,使得dist[vk]=min(dist[i] | vi∈V-S) ,vk为目前求得的下一条从v0出发的最短路径的终点。 将vk加入到S中
    (3) 修改从v0出发到集合V-S上任一顶点vi的最短路径的长度。如果 dist[k]+ g.arcs[k][i]<dist[i] 则将dist[i]修改为 dist[k]+ g.arcs[k][i] path[i]=path[k]+“vi”
    (4) 重复(2)、(3) n-1次,即可按最短路径长度的递增顺序,逐个求出v0到图中其它每个顶点的最短路径。

    const int MAX=1000; 
    void  Dijkstra(MGraph g, int v){        
    	for ( i =0; i<g.vexnum ; i++){   
    		dist[i]=g.arcs[v][i];                  
    		if ( dist[i]!= MAX)                        
    			path [i]=g.vertex[v]+g.vertex[i];
    		else                       
    			path[i]=“”;        
    	}        
    	S[0]=g.vertex[v];         
    	num=1;  
    	While (num<g.vextexNum){     
    		k=0;     
    		for(i=0;i<G.vertexNum;i++)            
    			if((dist[i]<dist[k])   
    				k=i     
    		cout<<dist[k]<<path[k];     
    		s[num++]=G.vertex[k];
    		for(i=0;i<G.vertexNum;i++)              
    			if(dist[k]+g.arc[k][i]<dist[i] {    
    				dist[i]=dist[k]+g.arc[k][i];                        
    				path[i]=path[k]+g.vertex[i];                
    			} 
    	} 
    }             

    每一对顶点之间的最短路径
    问题描述:给定带权有向图G=(V, E),对任意顶点vi,vj∈V(i≠j),求顶点vi到顶点vj的最短路径。
    解决办法1:每次以一个顶点为源点,调用Dijkstra算法n次。显然,时间复杂度为O(n3)。
    解决办法2:弗洛伊德提出的求每一对顶点之间的最短路径算法——Floyd算法,其时间复杂度也是O(n3),但形式上要简单些。
    Floyd算法的基本思想如下
    设图g用邻接矩阵法表示,求图g中任意一对顶点vi、 vj间的最短路径。 (-1) 将vi到vj 的最短的路径长度初始化为(vi,vj), 然后进行如下n次比较和修正:
    (0) 在vi、vj间加入顶点v0,比较(vi, v0, vj)和(vi, vj)的路径的长度,取其中较短的路径作为vi到vj的且中间顶点号不大于0的最短路径。
    (1) 在vi、vj间加入顶点v1,得(vi, …,v1)和(v1, …,vj),其中:(vi, …, v1)是vi到v1 的且中间顶点号不大于0的最短路径,(v1, …, vj) 是v1到vj 的且中间顶点号不大于0的最短路径,这两条路径在上一步中已求出。将(vi, …, v1, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于0的最短路径比较,取其中较短的路径作为vi到vj 的且中间顶点号不大于1的最短路径。
    (2) 在vi、vj间加入顶点v2,得(vi, …, v2)和(v2, …, vj), 其中:(vi, …, v2)是vi到v2 的且中间顶点号不大于1的最短路径,(v2, …, vj)是v2到vj 的且中间顶点号不大于1的最短路径,这两条路径在上一步中已求出。将(vi, …, v2, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于1的最短路径比较, 取其中较短的路径作为vi到vj 的且中间顶点号不大于2的最短路径。
    ……
    设计数据结构
    图的存储结构:带权的邻接矩阵存储结构
    数组dist[n][n]:存放在迭代过程中求得的最短路径长度。迭代公式
    dist-1[i][j]=arc[i][j],
    dist k[i][j]=min{distk-1[i][j], distk-1[i][k]+distk-1[k][j]}
    0≤ k ≤n-1
    数组path[n][n]: 存放从vi到vj的最短路径,初始为path[i][j]=“vivj”。
    Floyd算法——C++描述

    void Floyd(MGraph G) 
    {     
    	for (i=0; i<G.vertexNum; i++)                
    		for (j=0; j<G.vertexNum; j++)        
    		{           
    			dist[i][j]=G.arc[i][j];           
    			if (dist[i][j]!=)                 
    				path[i][j]=G.vertex[i]+G.vertex[j];           
    			else 
    				path[i][j]="";
    		}
    		for (k=0; k<G.vertexNum; k++)                  
    			for (i=0; i<G.vertexNum; i++)                   
    				for (j=0; j<G.vertexNum; j++)                
    					if (dist[i][k]+dist[k][j]<dist[i][j]) {
    						dist[i][j]=dist[i][k]+dist[k][j];                     
    						path[i][j]=path[i][k]+path[k][j];               
    					} 
    }
    展开全文
  • Dijkstra算法是求源点到其它顶点的最短路径怎样求任意两个顶点之间的最短路径
  • 多条最短路径的求解

    2015-01-09 13:21:44
    但是这个问题要求解多条最短路径,而迪杰斯特拉算法只能出其中一条最短路径及其距离,所以要在运用迪杰斯特拉算法算法的基础上,想想怎样求解多条最短路径。后来受到某个网友的启发,想到了一个解决办法,算法思想...
  • 因为课本上是打印出一条路径,然后我在想怎样能将所有的路径都输出来,方法:就是当出一条路径后,将出口点变成可以走的点(因为之前将其值变成了-1),并且将栈顶元素出栈,还需要得到现在栈顶元素的i,j,di值,...
  • /** * 还是最短路: 还是dijkstra * 但是! 按题意说的草儿一开始的城市,是一个可以用0的时间到输入给的几个出发城市的。...* 这样的话相当于源点到几个出发城市的距离都是0,如果只进行一次dijkstra会怎样? * 因为
  • Bell-man算法和Dijkstra算法都是最短路径的算法,都可以用于,单源点最短路径的问题,那么它们的区别在于什么呢? 想了很久,该怎样去总结它们的区别,最后我认为从两方面总结,是比较合适的:用途特性,算法...
  • 有abcdefg五个点a连着b和c,b连着d,e连着d,c,f和g。从a开始巡逻其中bcf点需要30分钟巡查一次,一次需要在那儿分别 呆3,2,3分钟。d,e则60分钟需巡逻一次,每次呆2,3分钟...现在在八小时内怎样安排最少人和路线。
  • 好吧 这道题第一个问题邮局位置就确定了,即将输入的x轴和y轴的数字排序取两者的中位数 两者的中位数就是邮局的位置 即到所有用户最短距离的位置 要问我为什么怎样 其实我自己也没搞太明白怎么找出的规律 不过在这...
  • 最小环

    2017-11-02 20:37:27
    1 定义: 通常来说最小环是针对有向图而言 从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的. 2.怎样求最小环呢?...求最短路径我们第一个想到的就是Dijkstra算法。而Di
  • floyd最小环

    2016-06-23 13:35:26
    floyd求最小环1 定义:通常来说最小环是针对有向图而言从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的.2....求最短路径我们第一个想到的就是Dijkstra算法。而Dijkstra所求
  • 【算法复习】Dijkstra寻图的最小路径

    千次阅读 2012-09-12 07:19:21
    在带非负权有向图中,提到求最短路径,Dijkstra算法是必然少不了的。而Dijkstra究竟能够怎样来求出最短路径,为了方便以后回顾,做一个比较。 Dijkstra算法适用于邻接矩阵的图的结构,采取贪心的方法,每次...
  • Floyd最小环

    2019-09-22 10:04:33
    本文转自这里  最小环:从一个点出发,经过一条简单路径回到起点成为环.... ... 怎样求最小环呢?... 1传统的解决方法(dijkstra): 任意一个最小环环的权值,我们都可以看成两个...求最短路径我们第一个想到的就Dijkstr...
  • 算法

    2008-08-07 11:30:26
    从A点(0,0)到B点(100,100)的最短路径 如路线上存在障碍物,绕过障碍物的最短路线 [b]问题补充:[/b] 其实我是自己无聊的时候在做html小游戏时遇到的问题, 我点击页面某一点, 然后页面中的小球则向我的...
  • 最小环

    2013-03-26 15:05:00
    1 定义: 通常来说最小环是针对有向图而言 从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的. 2.怎样求最小环呢?...求最短路径我们第一个想到的就是Dijkstra算法。而Dijk...
  • POJ 1125 Frogger (Floyd)

    2011-07-29 07:09:54
    青蛙从一号石头跳到二号石头,还有一些石头可以作为跳板,问选择怎样的路径...看了Discuss里做法很多,有求最小生成树的,有求最短路径的,其实个人感觉这题更像是Floyd的变形,更改Floyd的松弛条件为d[i][j]=min(d[i][j],max
  • 第一个问题还是一样,求最短路径。第二个问题是,假设我方有三个基地,经度、纬度分别为(70,40),(72,45),(68,48)。假设我方所有无人侦察机的速度都为1000 公里/小时。三个基地各派出一架飞机侦察敌方目标,...
  • 假如让你来设计一个连连看游戏的算法,你会怎么做呢?要求说明: 1.怎样用简单的计算机模型来描述这个问题?...3.怎样求出相同图形之间的最短路径? 4.怎样确定目前是处于死锁状态?如何设计算法来解决死锁?
  • hdu 4276 树形dp背包

    2013-08-06 08:28:21
     先用spfa出1至n的最短路径,并且将1到n最短路径上的边权致零,t减去dis【n】这样以后就可以不用考虑怎样回到n了,就和普通的树形dp一样, 状态方程 dp [ u ] [ j ] = max ( dp [ u ][ j ] ,dp[ v] [k ] +
  • 某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。例如:A + - + -- +...
  • Dijkstra算法和Floyd算法对比分析

    千次阅读 2018-01-15 11:11:54
    首先,Dijkstra算法与Floyd算法都是广度优先搜索的...都可以用来单源点到其他所有点的最短路径。那么这两者的原理分别是怎样?彼此又有什么区别呢? 此有向图中起点1到其他所有点的最短距离 在本文中,我们以一个
  • 求怎样走总的路径最短? 传统的方法:总的路径的条数=3*4*2=24条,分别出每条路径的长度,然后取最短的那条路径。这种算法可以出全局最短路径,但时间复杂度是O(N1*N2*....),将随着问题规模的扩大而迅速...
  • 都可以用来单源点到其他所有点的最短路径。那么这两者的原理分别是怎样?彼此又有什么区别呢?此有向图中起点1到其他所有点的最短距离在本文中,我们以一个小小的包含3个节点的有向图和邻接矩阵Graph来进行说明。...

空空如也

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

怎样求最短路径