hdu 3790 最短路径问题

用Dijsktra,考虑重边的情况。

#include <iostream>
#include<queue>
#include<stdio.h>
#include<cstring>
using namespace std;
typedef struct{
int di,p;}road;
road w[1005][1005],d[1005];
int visit[1005];
const int INF=100000000;
int main()
{
    int n,m,i,j,s,e,ok,temp_1,temp_2,dis,pa,re;
    while(scanf("%d %d",&n,&m)){
      if(n+m==0) break;
      memset(visit,0,sizeof(visit));
      for(i=1;i<=n;i++)
        for(j=1;j<=n;j++){
          w[i][j].di=INF;
          w[i][j].p=INF;
        }
      for(i=1;i<=m;i++){
        scanf("%d %d %d %d",&temp_1,&temp_2,&dis,&pa);
        if(w[temp_1][temp_2].di>dis) {                
          w[temp_1][temp_2].di=w[temp_2][temp_1].di=dis;
          w[temp_1][temp_2].p=w[temp_2][temp_1].p=pa;  
        }
         else if(w[temp_1][temp_2].di==dis)
          if(w[temp_1][temp_2].p>pa)
             w[temp_1][temp_2].p=w[temp_2][temp_1].p=pa;
        }
     /*注意这里不能合并写成if{(距离>=输入值)if(花费>输入值)更改花费} 
      eg:原来路径 时间值为3 2,若读入一组2 4,那么就会更新为2 2,但正确的应该是更新为2 4*/

        scanf("%d %d",&s,&e);
        for(i=1;i<=n;i++){
          d[i].di=(i==s?0:INF);
          d[i].p=(i==s?0:INF);
        }
     queue<int>q;
     q.push(s);
     visit[s]=1;
     while(!q.empty()){
       int temp=q.front();
       q.pop();
       int min=INF;
       ok=0;
       for(i=1;i<=n;i++){
         if(visit[i]==0&&i!=temp){
           if(d[i].di>d[temp].di+w[temp][i].di){
             d[i].di=d[temp].di+w[temp][i].di;
              d[i].p=d[temp].p+w[temp][i].p;
           }
            else if(d[i].di==d[temp].di+w[temp][i].di)
              if(d[i].p>d[temp].p+w[i][temp].p)
               d[i].p=d[temp].p+w[temp][i].p;

           if(d[i].di<min){
             re=i;
             min=d[i].di;
             ok=1;
           }
         }
       }
       if(ok==1){
       q.push(re);
       visit[re]=1;
     }
    }
     printf("%d %d\n",d[e].di,d[e].p);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值