最短路(队列优化)

题目描述

给定一张有向图,每条边有一个非负权值。并给出两个点,求这两个点之间最短路的长度。a、b之间的最短路指a出发到b的一条路径,使路径上的边权值之和最小。

输入

第一行包含4个非负整数n、m、a和b,其中n为点数,m为边数,a为起点的编号,b为终点的编号,a, b<n。下面m行,每行3个非负整数,x、y和c,x, y<n,表示一条从x到y的有向边,权值为c。数据保证至少存在一条路径可以从a到b。

输出

输出数据包含一个数,即所求最短路上所有边的权值之和。

样例输入 Copy

5 7 0 4
0 1 1
0 2 2
0 3 5
3 2 15
2 4 25
1 4 17
1 2 0

样例输出 Copy

18

提示

对于80%的数据,n≤1000,m≤10000;
对于100%的数据n≤20000,m≤40000,c≤10000。
#include<bits/stdc++.h>
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}
const int maxn=5e6+10;
int n,m,c;
int to[maxn],nxt[maxn],w[maxn];
int head[maxn];
int cnt=1;
void add(int x,int y,int z)
{
    to[cnt]=y;
    w[cnt]=z;
    nxt[cnt]=head[x];
    head[x]=cnt++;
}
struct node
{
    int x,d;
    bool operator <(const node& A) const
    {
        return d>A.d;
    }
};
bool vis[maxn];
int dis[maxn];
priority_queue<node>q;
node tmp;
void dijkstra(int s)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    tmp.x=s,tmp.d=0;
    q.push(tmp);
    dis[s]=0;
    while(!q.empty())
    {
        int x=q.top().x;q.pop();
        if(vis[x]) continue;
        vis[x]=1;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(dis[y]>dis[x]+w[i])
            {
                dis[y]=dis[x]+w[i];
                tmp.x=y,tmp.d=dis[y];
                q.push(tmp);
            }
        }
    }
}
int qd,zd;
void inint(){
    n=read(),m=read();
    qd=read(),zd=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read(),z=read();
        add(x,y,z);
    }
} 
int main()
{
    inint(); 
    dijkstra(qd);
    printf("%d
",dis[zd]);
    return 0;
}
原文地址:https://www.cnblogs.com/lipu123/p/13302187.html