• 洛谷P4779单源最短路(模板)


    题目描述

    给定一个 nnn 个点,mmm 条有向边的带非负权图,请你计算从 sss 出发,到每个点的距离。

    数据保证你能从 sss 出发到任意点。

    输入格式

    第一行为三个正整数 n,m,sn, m, sn,m,s。 第二行起 mmm 行,每行三个非负整数 ui,vi,wiu_i, v_i, w_iui,vi,wi,表示从 uiu_iuiviv_ivi 有一条权值为 wiw_iwi 的有向边。

    输出格式

    输出一行 nnn 个空格分隔的非负整数,表示 sss 到每个点的距离。

    输入输出样例

    输入 #1
    4 6 1
    1 2 2
    2 3 2
    2 4 1
    1 3 5
    3 4 3
    1 4 4
    输出 #1
    0 2 4 3


    #include<iostream>
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    #define WQD 2147483647
    #define maxn 10000001
    using namespace std;
    struct VD
    {
     int v,d;
     bool operator<(const VD&a)const
     {  return a.d<d;
     }
    };
    struct Edge
    {
     int to,w,next;
    };
    Edge edge[maxn];
    int head[maxn],u,v,d,dis[maxn],m,n,S,num=0;
    void add(int from,int to,int di)
    {
     edge[++num].next=head[from];
     edge[num].to=to;
     edge[num].w=di;
     head[from]=num;
    }
    void dijkstra(int s)
    {
     priority_queue<VD>q;
     for(int i=1;i<=n;i++) dis[i]=WQD;
     dis[s]=0;
     VD temp;
     temp.d=dis[s];temp.v=s;
     q.push(temp);
     while(!q.empty())
     {
      temp=q.top();
      q.pop();
      int p=temp.v;
      if(dis[p]<temp.d) continue;
      for(int i=head[p];i!=0;i=edge[i].next)
       if(dis[edge[i].to]>dis[p]+edge[i].w)
       {
        dis[edge[i].to]=dis[p]+edge[i].w;
        temp.v=edge[i].to;temp.d=dis[edge[i].to];
        q.push(temp);
       }
     }
     return;
    }
    int main()

     cin>>n>>m>>S;
     for(int i=1;i<=m;i++)
      {cin>>u>>v>>d;
      add(u,v,d);
      }
     dijkstra(S);
     for(int i=1;i<=n;i++)
      cout<<dis[i]<<' '; 
      return 0;
    }


    单源最短路dijkstra算法模板;
    void dijkstra(int s)
    {
     priority_queue<VD>q;
     for(int i=1;i<=n;i++) dis[i]=WQD;
     dis[s]=0;
     VD temp;
     temp.d=dis[s];temp.v=s;
     q.push(temp);
     while(!q.empty())
     {
      temp=q.top();
      q.pop();
      int p=temp.v;
      if(dis[p]<temp.d) continue;
      for(int i=head[p];i!=0;i=edge[i].next)
       if(dis[edge[i].to]>dis[p]+edge[i].w)
       {
        dis[edge[i].to]=dis[p]+edge[i].w;
        temp.v=edge[i].to;temp.d=dis[edge[i].to];
        q.push(temp);
       }
     }
     return;
    }
    用优先队列每次取最短的边遍历,优化时间;
    if(dis[p]<temp.d) continue;
    判断该temp对应的dis是否是该点最短路,若不是继续下一个点,减少遍历次数,优化了时间;
  • 相关阅读:
    c++ Oracle OCCI 编程
    linux库文件
    C/C++学习笔记 vector 和map基本操作总结
    linux 后台开发类常见问题及知识点
    Libmicrohttpd简介
    linux系统编程之进程(一):进程与程序
    回调函数
    va_start和va_end使用详解
    new在c#方法中的使用
    Android Studio快捷键
  • 原文地址:https://www.cnblogs.com/xcsj/p/12002824.html
Copyright © 2020-2023  润新知