HDU3790 最短路径问题(dijkstra+思维)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugarbliss/article/details/82996298

----------------------------------------------------传送门----------------------------------------------------

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 36746    Accepted Submission(s): 10772


 

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

思路:这题是在路径最短的境况下选择花费最少的,所以需要在松弛的时候对花费进行更新操作,假如说三个点被线连着,第一个点也连着第三个点,因为dij对边进行松弛的时候,总是选择在dis数组里面离远点最近的而且没松弛过的,所以从最短路径来说,这个点肯定是最短路径里的点了,但是如果加了花费这个条件的话,则和它走123路程相同而且更省钱的方法就是1直接到3,所以当我们判断如果dis[1-3]==dis[1-2-3]的话,我们就开始判断它们的花费的大小。

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int n, m, s, t;
int d[maxn],p[maxn];
vector<pair<int,int> >E[maxn];
vector<pair<int,int> >Ep[maxn];
void init()
{
    for(int i = 0; i < maxn; i++) d[i] = 1e9;
    for(int i = 0; i < maxn; i++) E[i].clear(),Ep[i].clear();
}
void Dijkstra()
{
    priority_queue<pair<int,int> >Q;
        Q.push(make_pair(-d[s],s));
        while(!Q.empty())
        {
            int now = Q.top().second;
            Q.pop();
            for(int j = 0; j < E[now].size(); j++)
            {
                int v = E[now][j].first;
                if(d[v] > d[now]+E[now][j].second)
                {
                    d[v] = d[now]+E[now][j].second;
                    p[v] = p[now]+Ep[now][j].second;
                    Q.push(make_pair(-d[v],v));
                }
                else if(d[v] == d[now]+E[now][j].second && p[v] > p[now]+Ep[now][j].second)
                    p[v] = p[now]+Ep[now][j].second;
            }
        }
}
int main()
{
    while(scanf("%d%d",&n,&m),n||m)
    {
        init();
        int a, b, x, c;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d%d",&a,&b,&x,&c);
            E[a].push_back(make_pair(b,x));
            E[b].push_back(make_pair(a,x));
            Ep[a].push_back(make_pair(b,c));
            Ep[b].push_back(make_pair(a,c));
        }
        scanf("%d %d",&s, &t);
        d[s] = 0; p[s] = 0; Dijkstra();
        printf("%d %d\n",d[t], p[t]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/82996298