HDU 1385 ZOJ 1456

这个字典序不是很难就是注意一下最短路相等的时候路径的跟新就好了;

具体解析见代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 1000000
using namespace std;
int map[55][55];//记录城市与城市之间的距离
int step[550];//记录路径
int cost[55];//记录经过城市的时候所需的税收
int mincost[55];//记录最短路
int n;//城市数
int judge[55];//这个就不解释了;
int star,end;//起点与终点
void output(int s, int target)//输出
{
    printf("Path: ");
    int t=s;
    printf("%d",t);
    while(true)
    {
        t=step[t];
         if(t==-1) break;
        printf("-->%d",t);
    }
    printf("\n");
    if(s!=target)
    printf("Total cost : %d\n",mincost[s]);
    if(s==target)
    printf("Total cost : 0\n");
    printf("\n");//这个少些了会PE
    return;
}
void solve(int s,int f)//DIJI算法主体
{
    memset(judge,0,sizeof(judge));
    memset(step,-1,sizeof(step));
    for(int i=0;i<=n;i++) mincost[i]=INF;
    //mincost[s]=0;
    mincost[f]=0;
    while(1)
    {
        int x=-1;
        for(int i=1;i<=n;i++)
        {
            if(judge[i]==0&&(x==-1||mincost[i]<mincost[x])) x=i;
        }
        if(x==-1) break;
        judge[x]=1;
        for(int i=1;i<=n;i++)
        {
            if(mincost[i]>map[i][x]+mincost[x]+cost[x])
            {
                step[i]=x;
                mincost[i]=map[i][x]+mincost[x]+cost[x];
            }
            else if(mincost[i]==map[i][x]+mincost[x]+cost[x])//就用这个IF搞定字典序输出的问题
            {
                if(step[i]==-1||step[i]>x)
                step[i]=x;
            }
        }
    }
    mincost[s]-=cost[f];//因为并未经过终点所以要把终点的税收减去;
    output(s,f);
}
int main()
{
    while(scanf("%d",&n)!=EOF&&n)
    {
        memset(map,-1,sizeof(map));
        memset(cost,0,sizeof(cost));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&map[i][j]);
                if(map[i][j]==-1) map[i][j]=INF;//用INF代替-1,方便一些
            }
        }
        for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
        /*for(int i=1;i<=n;i++)
        {
            printf("%d %d\n",i,cost[i]);
        }*/
        while(true)
        {
            scanf("%d%d",&star,&end);
            if(star==-1&&end==-1) break;
            printf("From %d to %d :\n",star,end);
            solve(star,end);
        }
    }
    return 0;
}
看见网上有人用二维数组标记路径,死活没看懂。。。。。。

不过还好我就的我的方法真的很实用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值