【洛谷P4779】【模板】单源最短路径(标准版)【最短路】

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P4779
给定一个 N N N个点, M M M条有向边的带非负权图,请你计算从 S S S出发,到每个点的距离。


思路:

d i j + dij+ dij+堆优化的最短路模板题。
其实就是在 S P F A SPFA SPFA中改成优先队列即可。和 S P F A SPFA SPFA基本一样。
时间复杂度: O ( ( n + m ) l o g   n ) O((n+m)log\ n) O((n+m)log n)


代码:

#include 
#include 
#include 
using namespace std;

const int N=100010;
const int M=200010;
int n,m,S,x,y,z,tot,dis[N],head[N];
bool vis[N];
priority_queue<pair<int,int> > q;

struct edge
{
    int next,to,dis;
}e[M];

void add(int from,int to,int dis)
{
    e[++tot].to=to;
    e[tot].dis=dis;
    e[tot].next=head[from];
    head[from]=tot;
}

void dij()
{
    q.push(make_pair(0,S));  //优先队列
    memset(dis,0x3f3f3f3f,sizeof(dis));
    dis[S]=0;
    while (q.size())
    {
        int u=q.top().second;  //取出点
        q.pop();
        if (vis[u]) continue;
        vis[u]=1;
        for (int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].to;
            if (dis[v]>dis[u]+e[i].dis)
            {
                dis[v]=dis[u]+e[i].dis;
                q.push(make_pair(-dis[v],v));  //入堆 
            }
        }
    }
}

int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d%d%d",&n,&m,&S);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    dij();
    for (int i=1;i<=n;i++)
        printf("%d ",dis[i]);
    return 0;
}

你可能感兴趣的:(最短路,洛谷模板题)