最短路径问题 变异Dijkstra

题目描述

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

输入

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示ab之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点tnm0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

输出

输出 一行有两个数, 最短距离及其花费。

样例输入

3 21 2 5 62 3 4 51 30 0

样例输出

9 11

     解题思路:dijkstra模板变形,首先路径最短是优先级最高的,之后才是费用问题,只有当路径出现相等的时间才有价值问题的比较。

代码:
#include<stdio.h>
#include<string.h>
int a[1010][1010];
int b[1010][1010];
int dis[1010];
int meny[1010];
int f[1010];
int main()
{
int i,j,k,inf,c1,min,sum,x1,x2,x3,x4,m,n;
inf=99999999;
while(scanf("%d%d",&m,&n),m+n!=0)
{
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
  if(i==j)
    {
 a[i][j]=0;
 b[i][j]=0;
}
   else
    {
 a[i][j]=inf;
 b[i][j]=inf;
}
memset(f,0,sizeof(f));
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
if(a[x1][x2]>x3)
{
a[x1][x2]=x3;
a[x2][x1]=x3;
b[x1][x2]=x4;
b[x2][x1]=x4;
}
}
scanf("%d%d",&x1,&x2);
for(i=1;i<=m;i++)
 {
  dis[i]=a[x1][i];
  meny[i]=b[x1][i];
 }
 f[x1]=1;
 c1=1;
 while(c1<m)
 {
   min=inf;
   for(i=1;i<=m;i++)
   {
    if(min>dis[i]&&f[i]==0)
    {
    min=dis[i];j=i;
 }
}
 f[j]=1;
 c1++;
 for(k=1;k<=m;k++)
 {
  if(a[j][k]<inf)
  {
  if(f[k]==0&&dis[k]>=dis[j]+a[j][k])
    {
    if(dis[k]==dis[j]+a[j][k]&&meny[k]>meny[j]+b[j][k])
      meny[k]=meny[j]+b[j][k];
    if(dis[k]>dis[j]+a[j][k])
{
dis[k]=dis[j]+a[j][k];
meny[k]=meny[j]+b[j][k];
}
}
 }
 }
 }
printf("%d %d\n",dis[x2],meny[x2]);
}
return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值