迪杰斯特拉模板Dijkstra(m*log(n))最短路 求最短距离及其花费 hnust1577

1577: 求最短距离及其花费

时间限制: 6 Sec  
内存限制: 33 MB

提交: 490  
解决: 139

[
提交][
状态][
讨论版]

题目描述

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

输入

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

输出

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

样例输入

3 2
1 2 5 6
2 3 4 5
1 3

样例输出

9 11

提示

本题是一个求最短路径的题目。首选Dijkstra算法,也可用Floyd算法!

来自紫书361页的模板,优化后的复杂度m*log(n)

#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define MT(x,i) memset(x,i,sizeof(x))
using namespace std;
const int MAX = 1005;

struct HeapNode{ //优先队列的节点
    int d,u,c;
    bool operator<(const HeapNode& rhs)const{
        if(d==rhs.d) return c>rhs.c;
        else return d>rhs.d;
    }
};

struct Edge{ //建图的边
    int from,to,dist,cost;
    Edge(int u,int v,int d,int c):from(u),to(v),dist(d),cost(c){}
};

struct Dijkstra{
    int n,m;
    vector<Edge>edges;//边
    vector<int>G[MAX];//存储边的编号
    bool done[MAX];//是否已永久标记
    int d[MAX];//dist距离
    int c[MAX];//cost花费
    int p[MAX];//上一条

    void init(int n){
        this->n=n;//this->m=m;
        for(int i=0;i<=n;++i) G[i].clear();
        edges.clear();
    }

    void AddEdge(int from,int to,int dist,int cost){
        edges.push_back(Edge(from,to,dist,cost));
        m=edges.size();
        G[from].push_back(m-1);
    }

    void dijkstra(int s){
        priority_queue<HeapNode>Q;
        for(int i=0;i<=n;i++) d[i]=INF;
        d[s]=0,c[s]=0;
        MT(done,0);
        Q.push((HeapNode){0,s,0});
        while(!Q.empty()){
            HeapNode x = Q.top(); Q.pop();
            int u=x.u;
            if(done[u]) continue;
            done[u]=true;
            for(int i=0;i<G[u].size();++i ){
                Edge& e=edges[G[u][i]];
                if(d[e.to]>d[u]+e.dist ||(d[e.to]==d[u]+e.dist&&c[e.to]>c[u]+e.cost) ){
                    d[e.to]=d[u]+e.dist;
                    c[e.to]=c[u]+e.cost;
                    p[e.to]=G[u][i];
                    Q.push((HeapNode){d[e.to],e.to,c[e.to]} );
                }
            }
        }
    }

};
Dijkstra dij;
int main()
{
    //freopen("F:\\1.txt","r",stdin);
    int N,M,a,b,d,c,s,t;
    while(~scanf("%d%d",&N,&M)){
        dij.init(N);
        for(int i=0;i<M;++i){
            scanf("%d%d%d%d",&a,&b,&d,&c); a--;b--; 
            dij.AddEdge(a,b,d,c);
            dij.AddEdge(b,a,d,c);
        }
        scanf("%d%d",&s,&t); s--;t--;
        dij.dijkstra(s);
        printf("%d %d\n",dij.d[t],dij.c[t]);
    }
    return 0;
}





    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/hnust_taoshiqian/article/details/46352631
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞