zoukankan      html  css  js  c++  java
  • 【原创】洛谷 LUOGU P3371 【模板】单源最短路径

    P3371 【模板】单源最短路径

    题目描述

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

    输入输出格式

    输入格式:

    第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

    接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

    输出格式:

    一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

    输入输出样例

    输入样例#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

    说明

    时空限制:1000ms,128M

    数据规模:

    对于20%的数据:N<=5,M<=15

    对于40%的数据:N<=100,M<=10000

    对于70%的数据:N<=1000,M<=100000

    对于100%的数据:N<=10000,M<=500000

    样例说明:

     
     
    很早以前写过Dijkstra,现在都快忘了。

    突然发现c++STL里的priority_queue就是堆,就重写了个堆优化。仍然是mhy12345大神风格 :)

    Dijkstra的思路:(贪心)

      将点分为已访问(vis[]==1)和未访问(vis[]==0)两组,

      dis[]存点到目前已访问的点集最短距离。

      每次在未访问的点集中选择一个dis[]最小的点加入已访问的点集,

      更新与该点相连的所有点dis[]值,

      直到所有点加到已访问的点集中即可。

      时间复杂度O(V^2),用堆优化(STL中的priority_queue虽然比手造堆常数略大,但用起来确实方便)即可降至O(VlogV)。

    代码如下:

     1 // LUOGU 3371 【模板】单源最短路径 
     2 // 2017.7.21 10:30
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<queue>
    10 #define MAXV 10010
    11 #define MAXE 500010
    12 #define INF 0x3f3f3f3f
    13 using namespace std;
    14 int n,m,s;
    15 struct Edge{
    16     int np,value;
    17     Edge *next;
    18 }E[MAXE],*V[MAXV];
    19 int tope=-1;
    20 int dis[MAXV];
    21 bool vis[MAXV];
    22 priority_queue<pair<int,int>,
    23                vector<pair<int,int> >,
    24                greater<pair<int,int> > > pq;
    25 void addedge(int u,int v,int w){
    26     E[++tope].np=v;
    27     E[tope].value=w;
    28     E[tope].next=V[u];
    29     V[u]=&E[tope];
    30 }
    31 int main(){
    32     scanf("%d%d%d",&n,&m,&s);
    33     for(int i=1;i<=m;i++){
    34         int u,v,w;
    35         scanf("%d%d%d",&u,&v,&w);
    36         addedge(u,v,w);
    37     }
    38     memset(dis,INF,sizeof(dis));
    39     memset(vis,0,sizeof(vis));
    40     dis[s]=0;
    41     pq.push(make_pair(dis[s],s));
    42     while(!pq.empty()){
    43         pair<int,int> mnvalue=pq.top();
    44         pq.pop();
    45         int nv=mnvalue.second;
    46         if(vis[nv])continue;
    47         vis[nv]=1;
    48         for(Edge *ne=V[nv];ne;ne=ne->next)
    49             if(dis[nv]+ne->value<dis[ne->np]){
    50                 dis[ne->np]=dis[nv]+ne->value;
    51                 pq.push(make_pair(dis[ne->np],ne->np));
    52             }
    53     }
    54     for(int i=1;i<=n;i++)
    55         if(dis[i]!=INF)printf("%d ",dis[i]);
    56         else printf("2147483647 ");
    57     printf("
    ");
    58     return 0;
    59 }
  • 相关阅读:
    BZOJ1264 [AHOI2006]基因匹配Match 动态规划 树状数组
    BZOJ1845 [Cqoi2005] 三角形面积并 扫描线 计算几何
    BZOJ1258 [CQOI2007]三角形tri 模拟
    BZOJ4972 八月月赛 Problem B 小Q的方格纸 二维前缀和
    BZOJ1218 [HNOI2003]激光炸弹 二维前缀和
    BZOJ1263 [SCOI2006]整数划分 高精度
    BZOJ1209 [HNOI2004]最佳包裹 三维凸包 计算几何
    BZOJ1207 [HNOI2004]打鼹鼠 动态规划
    BZOJ1202 [HNOI2005]狡猾的商人 spfa
    BZOJ1201 [HNOI2005]数三角形 大力出奇迹
  • 原文地址:https://www.cnblogs.com/darkleafin/p/7216615.html
Copyright © 2011-2022 走看看