这里先不放题 我们来说说这个模板需要用到哪些知识点
1.优先队列 (priority_queue)(用于优化) //这个百度一下就明白了
2.运算符重载 (洛谷好像不支持友元函数重载,会编译错误) (更改优先队列排序顺序) //同上 百度
3.BFS(思维核心) https://www.bilibili.com/video/av25829980 这个视频讲的很好,后半段的代码就不用看了 自己敲
4.链式前向星(用来存图) //https://blog.csdn.net/acdreamers/article/details/16902023 带你深入了解为何这样建图
一发A掉还是很开心的,自己其实也没想到 .
题目背景
2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。
然后呢?
100→60100 \rightarrow 60100→60 ;
Ag→CuAg \rightarrow CuAg→Cu ;
最终,他因此没能与理想的大学达成契约。
小 F 衷心祝愿大家不再重蹈覆辙。
题目描述
给定一个 NNN 个点, MMM 条有向边的带非负权图,请你计算从 SSS 出发,到每个点的距离。
数据保证你能从 SSS 出发到任意点。
输入输出格式
输入格式:
第一行为三个正整数 N,M,SN, M, SN,M,S 。 第二行起 MMM 行,每行三个非负整数 ui,vi,wiu_i, v_i, w_iui,vi,wi ,表示从 uiu_iui 到 viv_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 \leq N \leq 1000001≤N≤100000 ;
1≤M≤2000001 \leq M \leq 2000001≤M≤200000 ;
S=1S = 1S=1 ;
1≤ui,vi≤N1 \leq u_i, v_i\leq N1≤ui,vi≤N ;
0≤wi≤1090 \leq w_i \leq 10 ^ 90≤wi≤109 ,
0≤∑wi≤1090 \leq \sum w_i \leq 10 ^ 90≤∑wi≤109 。
本题数据可能会持续更新,但不会重测,望周知。
#include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define maxn 500005
#define mod 1e9+7
#define inf 2147483647
typedef long long ll;
ll n,m,s,ans[maxn],head[maxn],num,flag[maxn];
struct Why
{
ll next,now,dis;
}plat[maxn]; //结构体表示静态邻接表
struct Whhy
{
ll now,dis;
Whhy(ll x,ll y)
{
now = x;
dis = y;
}
bool operator < (const Whhy t) const //重载
{
return dis > t.dis;
}
};
void build(ll a,ll b,ll c) //链式前向星建图
{
plat[++num].next = head[a]; //链式存储下一条边
plat[num].now = b; //记录可以到达的当前节点编号
plat[num].dis = c; //记录到当前节点编号的距离
head[a] = num; //记录下一次出边情况
return ;
}
void bfs(ll x)
{
priority_queue<Whhy>A;
A.push( Whhy(x,0) );
while(!A.empty())
{
Whhy temp = A.top();
A.pop();
if( flag[temp.now] == 0 )
{
flag[ temp.now ] = 1;
if( temp.dis < ans[ temp.now ] ) //更新ans数组
ans[ temp.now ] = temp.dis;
for(ll i = head[temp.now]; i != 0; i = plat[i].next )
{
A.push( Whhy( plat[i].now, temp.dis+plat[i].dis) );
}
}
}
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> s;
for(ll i = 1; i <= m; i++)
{
ll a,b,c;
cin >> a >> b >> c;
build(a,b,c);
}
for(ll i = 1; i <= n; i++)
ans[i] = inf;
bfs(s);
for(ll i = 1; i <= n; i++)
cout << ans[i] << " ";
cout << endl;
return 0;
}