Floyd Test

算法思想:
      Floyd(弗洛伊德)算法的基本思想是:对一个顶点个数为n的有向网(或无向网),设置一个n×n的方阵A(k) ,其中除对角线的矩阵元素都等于0外,其他元素A(k) 

[i][j] (i≠j)表示从顶点vi到顶点vj的有向路径长度,k表示运算步骤,k = -1, 0, 1, 2, …, n-1。


初始时:A (-1)= Edge(图的邻接矩阵),即初始时,以任意两个顶点之间的直接有向边的权值作为最短路径长度:


1)  对于任意两个顶点vi和vj,若它们之间存在有向边,则以此边上的权值作为它们之间的最短路径长度;


2)  若它们之间不存在有向边,则以MAX作为它们之间的最短路径。以后逐步尝试在原路径中加入其他顶点作为中间顶点,如果增加中间顶点后,得到的路径比原来的最短路径长度减少了,则以此新路径代替原路径,修改矩阵元素,更新为新的更短的路径长度。



利用Floyd算法求图(a)中各顶点间的最短路径长度,并输出对应的最短路径。假设数据输入时采用如下的格式进行输入:首先输入顶点个数n,然后输入每条边的数据。每条边的数据格式为:u v w,分别表示这条边的起点、终点和边上的权值。顶点序号从0开始计起。最后一行为-1 -1 -1,表示输入数据的结束。


Floyd Test_第1张图片


#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 10;
const int INF = 10000000;

int A[MAXN][MAXN];
int Edge[MAXN][MAXN];
int path[MAXN][MAXN];
int n;


void Floyed()
{
    int i, j, k;
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
        {
            A[i][j] = Edge[i][j];
            if(i != j && A[i][j] < INF)
                path[i][j] = i;
            else
                path[i][j] = -1;
        }
    }

    for(k = 0; k < n; ++k)
    {
        for(i = 0; i < n; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                if(k == i || k == j)
                    continue;
                if(A[i][k] + A[k][j] < A[i][j])
                {
                    A[i][j] = A[i][k] + A[k][j];
                    path[i][j] = path[k][j];
                }
            }
        }
    }
}

int main()
{
    int i, j, t;
    int u, v, w;
    cin>>n;
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            Edge[i][j] = INF;

    for(i = 0; i < n; ++i)
        Edge[i][i] = 0;

    while(1)
    {
        cin>>u>>v>>w;
        if(u == -1 && v == -1 && w == -1)
            break;
        Edge[u][v] = w;
    }

    Floyed();

    int shortest[MAXN];

    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
        {
            if(i == j)
                continue;
            cout<<i<<" -> "<<j<<"\t"<<A[i][j]<<"\t";

            memset(shortest, 0, sizeof(shortest));

            int k = 0;
            shortest[k] = j;
            while( path[i][ shortest[k] ] != i )
            {
                k++;
                shortest[k] = path[i][ shortest[k-1] ];
            }
            k++;
            shortest[k] = i;
            for(t = k; t > 0; --t)
                cout<<shortest[t]<<" -> ";
            cout<<shortest[0]<<endl;
        }
    }
    return 0;
}



你可能感兴趣的:(最短路径)