hdu3790最短路径问题Dijkstra(迪杰斯特拉)

传送门

http://acm.hdu.edu.cn/showproblem.php?pid=3790
之前做过这道题,后来...后来忘了科科,思路很简单,就是迪杰斯特拉,加上一个限制条件(花费),在计算出最短路时,比较当前花费是不是同等路径长度下最少的。

错了好几次,发现是初始化存储边(两点之间的路径长度)数组时,没有直接把同等距离情况下,花费多的淘汰掉,导致存储了每次最后一个输入的路径长度和花费。

迪杰斯特拉还没掌握的可以看看下面这篇文章,我自己理解粗糙地说就是记录下起始点到各个目标点的距离,将其视为最短距离,后来若起始点经过别的点间接到达目标点的距离小于原来的最短距离,那么更新原来的最短距离(ps:批注都是后来码上去的,可能不小心删掉了源代码的一点内容?!望提醒!)

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

(之前代码好像乱了,我从hdoj上找到了题,就直接放上来了,就是没了注释)

#include<stdio.h>
#include<string.h>
#define MAX 1010 
#define MAx 0x7fffffff 
int map[MAX][MAX],count[MAX][MAX];
int vis[MAX],d[MAX],pay[MAX];
int n,m;
void djst(int Start)
{
    int i,j,k,Min,index,money;
    vis[Start]=1;
    for(i=1;i<=n;i++)
        {
            d[i]=map[Start][i];
            pay[i]=count[Start][i];
        }
    for(i=1;i<n;i++)
    {
        Min=MAx;
        for(k=1;k<=n;k++)
        {    
            if(vis[k]==0)
            {
                if(d[k]<Min)
                {
                    Min=d[k];//求出d数组中的最小值min
                    index=k;//求出d数组中的最小值的下标index 
                }
            }
        }
        vis[index]=1;
        for(j=1;j<=n;j++)
        {
            if(vis[j]==0&&map[index][j]<MAx)
            {
                if(Min+map[index][j]<d[j])
                {
                    d[j]=Min+map[index][j];//min和d[index]和map[Start][j]是同一个概念 
                    pay[j]=pay[index]+count[index][j];
                }
                else if(Min+map[index][j]==d[j])
                {
                    if(pay[j]>pay[index]+count[index][j])
                    {
                         
                        pay[j]=pay[index]+count[index][j];
                    }
                }
            } 
        }
    }
}
int main()
{
    int i,j,Start,End,len,worth,a,b;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            return 0;
        memset(vis,0,sizeof(vis));
        memset(pay,0,sizeof(pay));
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                map[i][j]=count[i][j]=MAx;
        for(i=1;i<=m;i++)
        {
            scanf("%d %d %d %d",&a,&b,&len,&worth);
            if(map[a][b]>len)
            {
                count[a][b]=count[b][a]=worth;
                map[a][b]=map[b][a]=len;
            }
            else if(map[a][b]==len&&count[a][b]>worth)
            {
                count[a][b]=count[b][a]=worth;
                map[a][b]=map[b][a]=len;
            }
        }
        scanf("%d %d",&Start,&End);
        djst(Start);
        printf("%d %d\n",d[End],pay[End]);
    }
    return 0;
} 

 


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值