poj3790 最短路径问题

最短路,用迪杰斯特拉算法做就行,不过要注意边的松弛条件,距离优先,先比较距离选择最小的,然后更新距离数组和价值数组,在距离相等的情况下再比较价值,选择价值最小的来更新;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int dis1[1100],dis[1100],e[1100][1100],bo[1100],e1[1100][1100];
int inf=1e10;

int main()
{
    int m,n,d,p,s,t,i,j,a,b,u,v,min;

    while(scanf("%d%d",&n,&m),m!=0||n!=0)
    {
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
                if(i==j)
                    e[i][j]=e1[i][j]=0;
                else
                    e[i][j]=e1[i][j]=inf;
        for(i=1; i<=m; i++)
        {
            scanf("%d%d%d%d",&a,&b,&d,&p);
            if(e[a][b]>d)//距离优先
            {
                e[a][b]=e[b][a]=d;
                e1[a][b]=e1[b][a]=p;
            }

            else if(e[a][b]==d)//距离相等的情况下再初始化价值
            {
                if(e1[a][b]>p)
                    e1[a][b]=e1[b][a]=p;
            }
        }
        scanf("%d%d",&s,&t);
        for(i=1; i<=n; i++)
        {
            dis[i]=e[s][i];
            dis1[i]=e1[s][i];
        }
        memset(bo,0,sizeof(bo));
        bo[s]=1;//一定要注意是bo[s]初始化为1,不要习惯性的将bo[1]初始化为1,从起点s点开始发展;
        for(i=1; i<n; i++)
        {
            min=inf;
            for(j=1; j<=n; j++)
            {
                if(bo[j]==0&&dis[j]<min)
                {
                    min=dis[j];
                    u=j;
                }
            }
            bo[u]=1;
            for(v=1; v<=n; v++)
            {
                if(bo[v]==0&&e[u][v]<inf)
                {
                    if(dis[v]>dis[u]+e[u][v])//先比较距离,选择最小的来更新两个数组
                    {
                        dis[v]=dis[u]+e[u][v];
                        dis1[v]=dis1[u]+e1[u][v];
                    }
                    else if(dis[v]==dis[u]+e[u][v])//距离相等,比较价值
                    {
                        if(dis1[v]>dis1[u]+e1[u][v])
                            dis1[v]=dis1[u]+e1[u][v];
                    }
                }
            }
        }
        printf("%d %d\n",dis[t],dis1[t]);//dis数组为距离数组,dis1数组为价值数组;
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值