Floyd得实现

测试数据:

输入:


4
0 1 1
0 3 4
1 2 9
1 3 2
2 0 3
2 1 5
2 3 8
3 2 6
-1 -1 -1

输出:

0=>1  1  0→1
0=>2  9  0→1→3→2
0=>3  3  0→1→3
1=>0  11   1→3→2→0
1=>2  8  1→3→2
1=>3  2  1→3
2=>0  3  2→0
2=>1  4  2→0→1
2=>3  6  2→0→1→3
3=>0  9  3→2→0
3=>1  10  3→2→0→1
3=>2  6    3→2

 

#include <cstdio>
#include <string>
#define INF    1000000    //无穷大
#define MAXN 20

int n;                    //顶点个数
int Edge[MAXN][MAXN];    //邻接矩阵
int A[MAXN][MAXN];        //
int path[MAXN][MAXN];    //

void Floyd( ) //假定图的邻接矩阵和顶点个数已经读进来了
{
    int i, j, k;
    for( i=0; i<n; i++ )
    {
        for( j=0; j<n; j++ )
        {
            A[i][j] = Edge[i][j];    //对a[ ][ ]初始化
            if( i!=j && A[i][j]<INF )  path[i][j] = i; //i到j有路径
            else path[i][j] = -1;    //从i到j没有直接路径
        }
    }
    //从A(-1)递推到A(0), A(1), ..., A(n-1),
    //或者理解成依次将v0,v1,...,v(n-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;    //循环变量
    int u, v, w;    //边的起点和终点及权值
    scanf( "%d", &n );    //读入顶点个数n
    for( i=0; i<n; i++ )    //设置邻接矩阵中每个元素的初始值为INF
    {
        for( j=0; j<n; j++ )  Edge[i][j] = INF;
    }
    for( i=0; i<n; i++ )    //设置邻接矩阵中对角线上的元素值为0
    {
        Edge[i][i] = 0;
    }
    while( 1 )
    {
        scanf( "%d%d%d", &u, &v, &w );    //读入边的起点和终点
        if( u==-1 && v==-1 && w==-1 )  break;
        Edge[u][v] = w;    //构造邻接矩阵
    }
    Floyd( );    //求各对顶点间的最短路径
    int shortest[MAXN];    //输出最短路径上的各个顶点时存放各个顶点的序号
    for( i=0; i<n; i++ )
    {
        for( j=0; j<n; j++ )
        {
            if( i==j )  continue;    //跳过
            printf( "%d=>%d\t%d\t", i, j, A[i][j] );    //输出顶点i到顶点j的最短路径长度
            //以下代码用于输出顶点0到顶点i的最短路径
            memset( shortest, 0, sizeof(shortest) );
            int k = 0;    //k表示shortest数组中最后一个元素的下标
            shortest[k] = j;
            while( path[i][ shortest[k] ] != i )
            {
                k++; shortest[k] = path[i][ shortest[k-1] ];
            }
            k++; shortest[k] = i;
            for( int t=k; t>0; t-- )
                printf( "%d→", shortest[t] );
            printf( "%d\n", shortest[0] );
        }
    }
    return 0;
}

 

posted @ 2013-07-31 16:30  哥的笑百度不到  阅读(134)  评论(0编辑  收藏  举报