洛谷 P4779 :【模板】单源最短路径(标准版)(Dijkstra+堆优化+链式前向星)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/wang_123_zy/article/details/82497369

题目背景

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

然后呢?

100→60;

Ag→Cu;

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

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

题目描述

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

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

输入输出格式

输入格式:

第一行为三个正整数 N, M, S。 第二行起 M 行,每行三个非负整数 u_{i},v_{i},w_{i},表示从 u_{i}到 v_{i} 有一条权值为 w_{i}的边。

输出格式:

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

输入输出样例

输入样例#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\leq N\leq 100000

1\leq M\leq 200000

S=1

1\leq u_{i},v_{i}\leq N

0\leq w_{i}\leq 10^{9}

0\leq \sum w_{i}\leq 10^{9}

本题数据可能会持续更新,但不会重测,望周知。

2018.09.04 数据更新 from @zzq

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <limits.h>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <string>
#define ll long long
#define ull unsigned long long
#define ms(a) memset(a,0,sizeof(a))
#define msf(a) memset(a,INF,sizeof(a))
#define msy(a) memset(a,-1,sizeof(a))
#define pi acos(-1.0)
#define INF 0x7f7f7f7f
#define lson o<<1
#define rson o<<1|1
const double E=exp(1);
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
inline 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;
}
struct wzy
{
	int Next,to,w;
}edge[maxn];
int cnt;
int n,m;
int head[maxn];
int dis[maxn];
struct node
{
	int u,d;
	bool operator < (const node& dui) const {return d>dui.d;}
};
inline void add(int u,int v,int w)
{
	edge[cnt].Next=head[u];
	edge[cnt].w=w;
	edge[cnt].to=v;
	head[u]=cnt++;
}
inline void dijkstra(int a)
{
	msf(dis);
	priority_queue<node>q;
	q.push(node{a,0});
	dis[a]=0;
	while(!q.empty())
	{
		node res=q.top();q.pop();
		int u=res.u,d=res.d;
		/////////////////////
		// 注意:没有下面这个会超时!!! 
		/////////////////////
		if(d!=dis[u])
			continue;
		for(int k=head[u];~k;k=edge[k].Next)
		{
			int v=edge[k].to,w=edge[k].w;
			if(dis[v]>dis[u]+edge[k].w)
			{
				dis[v]=dis[u]+w;
				q.push((node){v,dis[v]});
			}
		}
	}
}
int main(int argc, char const *argv[])
{
	int n,m,s;
	msy(head);
	n=read();m=read();s=read();
	int x,y,z;
	while(m--)
	{
		x=read();y=read();z=read();
		add(x,y,z);
	}
	dijkstra(s);
	for(int i=1;i<=n;i++)
	{
		printf("%d ",dis[i]);
	}
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wang_123_zy/article/details/82497369