HDOJ-1385Minimum Transport Cost(记录路径且有点权的FLOYD)

题意:给出一个图的邻接矩阵,即任意两点之间的边权,再给出给个点的权值。再询问两个点之间的最短路(路径上除了始点和终点之外的点权+边权),并输出最短路路径,若有多条最短路,输出字典序小的。

解法:

主体还是Floyd,关于点权的处理,更新时的条件变为:f[i][j]=min(f[i][k]+f[k][j]+d[k])。

关于路径的记录,用path[i][j]表示从点i到点j的最短路上,从i点出发后到达的第一个点是哪个点。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 512

int n;
int f[N][N],tax[N],path[N][N];

int min(int x,int y)
{
    return x<y?x:y;
}

void Init()
{
    int i,j,d;
    memset(f,0X3F,sizeof(f));
    for(i=0;i<=n;i++) f[i][i]=0;

    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            scanf("%d",&d);
            if(d!=-1) f[i][j]=d;
            path[i][j]=j;//路径记录的初始化
        }

    for(i=1;i<=n;i++) scanf("%d",&tax[i]);
}

void Floyd()
{
    int i,j,k,d;

    for(k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                //右侧表达式中加上了经过点的权值
                d=f[i][k]+f[k][j]+tax[k];

                if(d<f[i][j])
                {
                    //根据距离大小判断是否要更新
                    f[i][j]=d;
                    path[i][j]=path[i][k];
                }
                else if(d==f[i][j])
                {
                    //根据字典序判断是否要更新路径
                    path[i][j]=min(path[i][j],path[i][k]);
                }
            }
}

void Output()
{
    int i,j,k,x,y;
    while(scanf("%d%d",&x,&y),!(x==-1 && y==-1))
    {
        k=x; j=y;
        printf("From %d to %d :\n",k,j);
        printf("Path: %d", k);
        while(k!=j)
        {
            //依次输出路径直到到达终点
            printf("-->%d",path[k][j]);
            k=path[k][j];
        }
        printf("\n");
        printf("Total cost : %d\n\n", f[x][y]);
    }

}


int main()
{
    while(scanf("%d",&n),n)
    {
        Init();
        Floyd();
        Output();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值