码迷,mamicode.com
首页 > 其他好文 > 详细

P3371 【模板】单源最短路径(弱化版)

时间:2020-01-19 22:07:01      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:struct   ble   复制   one   line   time   测试数据   一点   路径   

P3371 【模板】单源最短路径(弱化版)

题目背景

本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779

题目描述

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

输入格式

第一行包含三个整数 n,m,sn,m,s,分别表示点的个数、有向边的个数、出发点的编号。

接下来 mm 行每行包含三个整数 u,v,wu,v,w,表示一条 u \to vuv 的,长度为 ww 的边。

输出格式

输出一行 nn 个整数,第 ii 个表示 ss 到第 ii 个点的最短路径,若不能到达则输出 2^{31}-12311。

输入输出样例

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

说明/提示

【数据范围】
对于 20\%20% 的数据:1\le n \le 51n5,1\le m \le 151m15;
对于 40\%40% 的数据:1\le n \le 1001n100,1\le m \le 10^41m104;
对于 70\%70% 的数据:1\le n \le 10001n1000,1\le m \le 10^51m105;
对于 100\%100% 的数据:1 \le n \le 10^41n104,1\le m \le 5\times 10^51m5×105,保证数据随机。

对于真正 100\%100% 的数据,请移步 P4779。请注意,该题与本题数据范围略有不同。

样例说明:

技术图片

图片1到3和1到4的文字位置调换

思路

这里使用使用STL队列,首先用数组dis记录起点到每个结点的最短路径,用邻接表来存储图,用vis数组记录当前节点是否在队列中

具体操作

用队列来保存待优化的结点(类似于BFS),优化时每次取出队首结点,并且用队手节点来对最短路径进行更新并进行松弛操作

如果要对所连点的最短路径需要更新,且改点不在当前的队列中,就将改点加入队列然后不断进行松弛操作,直至队列空为止。

AC代码如下

技术图片
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0,k=1; char c=getchar();
    while(c<0||c>9){if(c==-)k=-1;c=getchar();}
    while(c>=0&&c<=9)x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*k;
}
#define maxn 10005
#define maxm 500005
#define inf 2147483647
int n,m,s,tot,di[maxn],t[maxn];
bool vi[maxn];
struct e
{
      int next,to,w;
}h[maxm];
void add(int u,int v,int w)
{
    h[++tot].next=t[u];
    h[tot].to=v;
    h[tot].w=w;
    t[u]=tot;
}
queue<int> q;
inline void sp()
{
    for(int i=1; i<=n; i++)
    {
        di[i]=inf;
    }
    int u,v;
    q.push(s);
    di[s]=0; 
    vi[s]=1;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        vi[u]=0;
        for(int i=t[u];i;i=h[i].next)
        {
            v=h[i].to;
            if(di[v]>di[u]+h[i].w)
            {
                di[v]=di[u]+h[i].w;
                if(!vi[v])
                {
                      vi[v]=1;
                      q.push(v);
                }
            }
        }
    }
}
int main(){
    n=read(),m=read(),s=read();
    for(int i=1,u,v,w;i<=m;i++)
    {
        u=read(),v=read(),w=read();
        add(u,v,w);
    }
    sp();
    for(int i=1; i<=n; i++)
    {
        printf("%d ",di[i]);
    }
    return 0;
}
View Code

注意

这里需要注意一点,就是在原题中的一个条件“如果没有结果,则输出2^31-1”.

本人就是在这里丢掉了一个测试点的分QWQ。

P3371 【模板】单源最短路径(弱化版)

标签:struct   ble   复制   one   line   time   测试数据   一点   路径   

原文地址:https://www.cnblogs.com/Michael666/p/12215710.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!