HDU - 3790 最短路径问题(Dijkstra)

时间:2022-04-22 09:40:39

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790

#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX 10000005
#define N 1005
using namespace std;
/****************************************************************************************************************
            题意:在最短路径的基础上,输出花费最小的那个路径
            思路:
            1,dijkstra找最短路径
            2,在每次更新路径长度的同时更新花费即可
****************************************************************************************************************/
int visit[N];       //用来判断是非在特殊路径集合点内
int dist[N],cost[N];
int a[N][N],V[N][N];
int dijkstra(int start,int End,int n)
{
    for(int i = 1;i <= n;i ++){
        dist[i]=a[start][i];
        cost[i]=V[start][i];
    }
    memset(visit,0,sizeof(visit));

    dist[start]=0;
    //cost[start]=0;
    visit[start]=1;

    for(int i = 1;i < n;i ++){
        int id=1,ansN=MAX;
        for(int j = 1;j <= n;j ++){
            if(!visit[j] && dist[j] < ansN){        //在S集合外找出最小路径点(即非特殊路径)
                ansN=dist[j];
                id=j;
            }
        }

        visit[id]=1;
        for(int j = 1;j <= n;j ++){     //以找到的最小路径点为最优解进行动态更新(非特殊路径集合点内遍历)
            if(!visit[j] && a[id][j] < MAX){
                if(dist[j] > dist[id]+a[id][j]){
                    dist[j]=dist[id]+a[id][j];
                    cost[j]=cost[id]+V[id][j];      //更新花费
                }
                else if(dist[j] == dist[id]+a[id][j]){
                    if(cost[j] > cost[id]+V[id][j])
                        cost[j]=cost[id]+V[id][j];      //更新花费
                }
            }
        }
        //if(id == End)   return 0;
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m) != EOF)
    {
        if(n == 0 && m == 0)    break;
        for(int i = 1;i <= n;i ++){
            for(int j = 1;j <= n;j ++){
                a[i][j]=MAX;
                V[i][j]=MAX;
            }
            dist[i]=MAX;
            cost[i]=MAX;
        }
        //memset(dist,MAX,sizeof(dist));

        int A,B,C,D;
        for(int i = 1;i <= m;i ++){
            scanf("%d%d%d%d",&A,&B,&C,&D);
            if(C < a[A][B]){
                a[A][B]=a[B][A]=C;
                V[A][B]=V[B][A]=D;
            }
            else if(C == a[A][B]){
                if(D < V[A][B])
                    V[A][B]=V[B][A]=D;
            }
        }
        int Start,End;
        cin>>Start>>End;

        dijkstra(Start,End,n);
        cout<<dist[End]<<" "<<cost[End]<<endl;
    }
    return 0;
}