洛谷4779标准版最短路

题目背景

2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。

然后呢?

100→60100 \rightarrow 6010060 ;

Ag→CuAg \rightarrow CuAgCu ;

最终,他因此没能与理想的大学达成契约。

而其实,这样的同学不只一位,小 F 就认识两位。

小 F 衷心祝愿大家不再重蹈覆辙。

题目描述

给定一个 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

说明

样例解释请参考 数据随机的模板题

1≤N≤1000001

1≤M≤2000001

1≤ui,vi,S≤N

0≤wi≤1050

0≤∑wi≤1090

题解:

堆优化迪杰斯特拉,不要犹豫,SPFA会被卡成n^2的。其中,加入判断点是否松弛过的数组,判断后使用continue,还有快读也必不可少。

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue> 
#define pi pair<int,int>
using namespace std;
const int maxn=100001,maxm=500003;
int n,m,S;
int fir[maxn],nex[maxm],w[maxm],to[maxm],fa[maxn],vis[maxn];
long long dis[maxn];
priority_queue<pi,vector<pi>,greater<pi> >q;
int read() 
{
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=(X<<3)+(X<<1)+c-'0',c=getchar();
    return X*w;
}
void mem()
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        dis[i]=2147483647;
        fa[i]=0;
    }
    dis[S]=0;
}
void Dijkstra()
{
    mem();
    q.push(make_pair(0,S));
    while(!q.empty())
    {
        int k=q.top().second;
        q.pop();
        if(vis[k]) continue;
        vis[k]=true;
        for(int i=fir[k];i!=-1;i=nex[i])
        {
            if(vis[to[i]])continue;
            if(dis[to[i]]>dis[k]+w[i])
            {
                dis[to[i]]=dis[k]+w[i];
                fa[to[i]]=k;
                q.push(make_pair(dis[to[i]],to[i]));
            }
        }
    }
}
int main()
{
    memset(fir,-1,sizeof(fir));
    memset(vis,0,sizeof(vis));
    n=read(),m=read(),S=read();
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        w[i]=z;
        to[i]=y;
        nex[i]=fir[x];
        fir[x]=i;
    }
    Dijkstra();
    for(int i=1;i<=n;i++)
    {
        printf("%lld",dis[i]);
        if(i!=n)printf(" ");
    }
    return 0;
} 

 

 

 

转载于:https://www.cnblogs.com/czktransformers/p/9359477.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值