HDOJ 1385 Minimum Transport Cost(dijkstar+字典路径||floyd+字典路径)


题目链接:。。。。。。。。。


题目大意:开始时输入n表示一个n*n的矩阵, 该矩阵表示从i到j要多少钱, 然后输入经过每个城市时要的税, 起点和终点不需要缴税。要求输出最小花费路径, 并是字典顺序。

Ps:法克, 输出格式时比如1到1是 Path: 1, 而不是Path: 1-->1;就这个法克错一下午啊!


code:dijkstar+字典路径

#include <stdio.h>
#include <string.h>
#define inf 0x7fffffff
int n = 0, start = 0, end = 0, map[1002][1002], tax[1002], path[1002], used[1002], dis[1002];
int cmp(int a, int b, int c)
{
    int cur = 0, path1[1002] = {0}, path2[1002] = {0}, count1 = 0, count2 = 0;
    path1[count1++] = c, path2[count2++] = c;//path1与path2存的是到c点的路径
    for(cur = a; cur != -1; cur = path[cur])
        path1[count1++] = cur;
    for(cur = b; cur != -1; cur = path[cur])
        path2[count2++] = cur;
    count1--, count2--;
    while(count1 != -1 || count2 != -1)
    {
        if(path1[count1]>path2[count2])
            return b;
       else if(path1[count1]<path2[count2])
            return a;
        count1--, count2--;
    }
    if(count1 == -1)
        return a;
    else
        return b;
}
void dijkstar()
{
    int i = 0, j = 0, k = 0, min = 0;
    for(i = 1; i<=n; i++)
    {
        path[i] = -1;
        used[i] = 0;
    }
    for(i = 1; i<=n; i++)
    {
        dis[i] = map[start][i];
    }
    used[start] = 1;
    for(i = 0; i<n; i++)
    {
        min = inf;
        for(j = 1; j<=n; j++)
            if(!used[j] && min>dis[j] )
            {
                min = dis[j];
                k = j;
            }
        used[k] = 1;
        for(j = 1; j<=n; j++)
        {
            if(map[k][j] == inf) continue;
            if(!used[j] && dis[j]>dis[k]+map[k][j]+tax[k])
            {
                dis[j] = dis[k]+map[k][j]+tax[k];
                path[j] = k;
            }
            else if(!used[j] && dis[j]==dis[k]+map[k][j]+tax[k])//选取字典序小的
            {
                path[j] = cmp(path[j], k, j);//判断j的前面是path[j]还是k
            }
        }
    }
}
void print(int cur)
{
    if(path[cur] != -1)
        print(path[cur]);
    printf("-->%d", cur);
}
int main()
{
    int i = 0, j = 0;
    while(scanf("%d",&n) , n)
    {
        for(i = 1; i<=n; i++)
            for(j = 1; j<=n; j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j] == -1)
                    map[i][j] = inf;
            }
        for(i = 1; i<=n; i++)
            scanf("%d",&tax[i]);
        while(scanf("%d %d",&start, &end), start != -1 && end != -1)
        {
            dijkstar();
            printf("From %d to %d :\nPath: %d", start, end, start);
            if(start != end)
                print(end);
            printf("\n");
            printf("Total cost : %d\n\n",dis[end]);
        }
    }
    return 0;
}




code: floyd+字典路径

path[i][j] 中存的是i到j路径的第2个点, 比如1->2->3, path[1][3]存的是2, path[2][3] = 3;

#include <stdio.h>
#include <string.h>
#define inf 0x7fffffff
int n = 0, start = 0, end = 0, map[1002][1002], tax[1002], path[1002][1002];
void floyd()
{
    int i = 0, j = 0, k = 0, item = 0;
    for(i = 1; i<=n; i++)
        for(j = 1; j<=n; j++)
            path[i][j] = j;
    for(k = 1; k<=n; k++)
        for(i = 1; i<=n; i++)
        {
            if(i == k) continue;
            for(j = 1; j<=n; j++)
            {
                if(map[i][k] == inf || map[k][j] == inf) continue;
                item = map[i][k]+map[k][j]+tax[k];
                if(map[i][j]>item)
                {
                    map[i][j] = item;
                    path[i][j] = path[i][k];
                }
                else if(path[i][j]>path[i][k] && map[i][j]==item)
                    path[i][j] = path[i][k];
            }
        }
}
void print()
{
    int cur = start;
    printf("From %d to %d :\nPath: %d", start, end, start);
    while(cur != end)
    {
        printf("-->%d",path[cur][end]);
        cur = path[cur][end];
    }
    printf("\nTotal cost : %d\n\n", map[start][end]);
}
int main()
{
    int i = 0, j = 0;
    while(scanf("%d",&n) , n)
    {
        for(i = 1; i<=n; i++)
        {
            for(j = 1; j<=n; j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j] == -1)
                    map[i][j] = inf;
            }
        }
        for(i = 1; i<=n; i++)
            scanf("%d",&tax[i]);
        floyd();
        while(scanf("%d %d",&start, &end), start != -1 && end != -1)
        {
            print();
        }
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值