hdu 3790 最短路径问题(dijkstra加强版)

hdu 3790 最短路径问题

http://acm.hdu.edu.cn/showproblem.php?pid=3790

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

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

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

Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
 

Sample Output
9 11

dijkstra算法:

#include<iostream>
using namespace std;
#define INF 9999999
#define MAX 1010
struct nod
{
 int d,p;
}map[MAX][MAX];
int dis[MAX],v[MAX],pay[MAX];
void dijkstra(int s,int n)
{
 int i,j,k,mind;
 for(i=1;i<=n;i++)
 {
  dis[i]=map[s][i].d;
  pay[i]=map[s][i].p;
 }
 memset(v,0,sizeof(v));
 v[s]=1;
 pay[s]=dis[s]=0;
 for(i=2;i<=n;i++)
 {
  k=s;
  mind=INF;
  for(j=1;j<=n;j++)
   if(!v[j]&&dis[j]<mind)
   {
    k=j;
    mind=dis[j];
   }
  v[k]=1;
  for(j=1;j<=n;j++)
   if(!v[j]&&map[k][j].d<INF)    
   {
    if(dis[j]>dis[k]+map[k][j].d)
    {
     dis[j]=dis[k]+map[k][j].d;
     pay[j]=pay[k]+map[k][j].p;
    }
    else if(dis[j]==dis[k]+map[k][j].d)
    {
     if(pay[j]>pay[k]+map[k][j].p)
      pay[j]=pay[k]+map[k][j].p;
    }
   }
 }
}
int main()
{
 int n,m,a,b,d,p,s,t;
 while(~scanf("%d%d",&n,&m))
 {
  if(n==0&&m==0)
   break;
  int i,j;
  for(i=1;i<=n;i++)
   for(j=1;j<=n;j++)
    map[i][j].d=map[i][j].p=INF;
  for(i=1;i<=m;i++)
  {
   scanf("%d%d%d%d",&a,&b,&d,&p);
   if(map[a][b].d>d)
   {
    map[a][b].d=map[b][a].d=d;
    map[a][b].p=map[b][a].p=p;
   }
   else if(map[a][b].d==d)
    map[a][b].p=map[b][a].p=p;
  }
  scanf("%d%d",&s,&t);
  dijkstra(s,n);
  printf("%d %d\n",dis[t],pay[t]);
 }
 return 0;
}

原文地址:https://www.cnblogs.com/crazyapple/p/2999481.html