题目链接:
dijkstra最短路模板 :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
inline int read()
{
register int x = 0, f = 1;
register char c = getchar();
while(c > '9' || c < '0')
{
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * f;
}
// 解题思路:
// dijkstra模板
const int maxn = 1e4 + 5;
const int maxm = 5e5 + 5;
// 定义边的结构体
struct edge
{
edge(){}
edge(int v, int w, int next)
:v(v), w(w), next(next)
{}
int v, w, next;
}e[maxm];
// size是存放边的位置,head[u]是节点u的第一条边
// 通过next找到下一条边,链式前向星存图法
int size = 0, head[maxn];
void insert(int u, int v, int w)
{
// 插入一条新边
e[size] = edge(v, w, head[u]);
head[u] = size++;
}
// 建图
void build_graph(int m)
{
memset(head, -1, sizeof(head));
int u, v, w;
for(int i = 1; i <= m; i++)
{
u = read(); v = read(); w = read();
insert(u, v, w);
}
}
// 查找未加入确定最短路径集合的最短距离节点的堆优化
struct node
{
int id, dis;
bool operator<(const node &r) const
{
return dis > r.dis;
}
};
priority_queue<node> q;
int d[maxn];
bool vis[maxn];// 出队时加入确定集合则标记
void dijkstra(int u)
{
// 将距离数组初始化为inf
memset(d, 0x3f, sizeof(d));
// 将起点入队
q.push((node){u, 0});
d[u] = 0;
while(!q.empty())
{
// 将最短距离点出队,标记,加入已确定最短距离集合
node t = q.top();
q.pop();
if(vis[t.id]) continue;
vis[t.id] = true;
// 遍历该点所有边,更新相邻节点的最短距离
for(int i = head[t.id]; ~i; i = e[i].next)
{
int v = e[i].v;
int w = e[i].w;
// 如果之前已标记过则不再更新
if(!vis[v] && t.dis + w < d[v])
{
// 更新后入队
d[v] = t.dis + w;
q.push((node){v, d[v]});
}
}
}
}
int main()
{
int n, m, s;
n = read(); m = read(); s = read();
build_graph(m);
dijkstra(s);
for(int i = 1; i <= n; i++)
{
if(d[i] > 1e9)
{
printf("2147483647 ");
}
else
printf("%d ", d[i]);
}
return 0;
}
SPFA模板:(待写)