Floyd最短路及路径输出

引例

下图表示城市之间的交通路网,线段上的数字表示费用。如图,求$V_{1}$→$V_{n}$最短路径长度及路径

样例数据

输入

10
0 2 5 1 0 0 0 0 0 0
0 0 0 0 12 14 0 0 0 0
0 0 0 0 6 10 4 0 0 0
0 0 0 0 13 12 11 0 0 0
0 0 0 0 0 0 0 3 9 0
0 0 0 0 0 0 0 6 5 0
0 0 0 0 0 0 0 0 10 0
0 0 0 0 0 0 0 0 0 5
0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0

输出

minlong=19
1 3 5 8 10

分析

用$Dp$数组记录状态并初始化之为$INF$,如果输入的$G_{i, j}$不是0则$Dp_{i, j}$ = $G_{i, j}$。裸$Floyd$,$Path$数组记录路径,递归输出,输出时勿忘判断此时是否存在$Path$,且要先输出1因为从1开始且1不会被判断到

代码

#include <bits/stdc++.h>

#define Enter puts("")
#define Space putchar(' ')

using namespace std;

typedef long long ll;
typedef double Db;

const int INF = 0x3f3f3f;

//template <typename T>

inline ll Read()
{
    ll Ans = 0;
    char Ch = getchar() , Las = ' ';
    while(!isdigit(Ch))
    {
        Las = Ch;
        Ch = getchar();
    }
    while(isdigit(Ch))
    {
        Ans = (Ans << 3) + (Ans << 1) + Ch - '0';
        Ch = getchar();
    }
    if(Las == '-')
        Ans = -Ans;
    return Ans;
}

inline void Write(ll x)
{
    if(x < 0)
    {
        x = -x;
        putchar('-');
    }
    if(x >= 10)
        Write(x / 10);
    putchar(x % 10 + '0');
}

int G[1001][1001];
int n;
int Dp[1001][1001];
int Path[1001][1001];

inline void Print_Path(int x , int y)
{
    if(x == y) 
    {
        printf("%d" , x);
        return ;
    }
    int k = Path[x][y];
    if(Path[x][y])
        Print_Path(x , k);        
    printf("%d " , y);
}

/*inline void Init()
{ 
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= n; j ++ )
        {
            if(i == j) 
                Dp[i][j] = 0;
            else 
                Dp[i][j] = INF;
            Path[i][j] = i;
        }            
}*/

int main()
{
    n = Read();
    //Init();
    memset(Dp , INF , sizeof(Dp));
    for(int i = 1; i <= n; i++)    
        for(int j = 1; j <= n; j++)
        {
            G[i][j] = Read();
            if(G[i][j])
                Dp[i][j] = G[i][j];    
        }
/*    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            if(!Dp[i][j]) 
                Dp[i][j] = INF;
*/
    for(int i = 1; i <= n; i++)
        Dp[i][i] = 0;
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                if(Dp[i][j] > Dp[i][k] + Dp[k][j])
                {
                    Dp[i][j] = Dp[i][k] + Dp[k][j];
                    Path[i][j] = k;
                }
            }
    printf("minlong=%d" , Dp[1][n]);
    Enter;
    cout << "1 ";
    Print_Path(1 , n);
    return 0;
}

 

posted @ 2021-04-20 20:39  Tenderfoot  阅读(192)  评论(0编辑  收藏  举报