题目描述
给定 M 条边, N 个点的带权无向图,求 1到 N 的最短路。
注意图中可能有重边和自环,数据保证 1 到 N 有路径相连。
输入格式
第一行:N,M;
接下来 M 行 3 个正整数:ai, bi, ci 表示 ai, bi 之间有一条长度为 ci 的路;
输出格式
一个整数,表示 1 到 N 的最短距离。
输入样例
4 4
1 2 1
2 3 1
3 4 1
2 4 1
输出样例
2
数据范围
N ≤ 105,M ≤ 5 × 105,ci ≤ 1000
题解
SPFA && 链式前向星:
注意事项
:
- 输入规模达到了 105 级别,因此要用
scanf
读入; - 由于是无向图,所以要建两条有向边,因此边的范围要开到
1e6 + 10
;
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1e5 + 10, M = 1e6 + 10;
int n, m;
bool st[N];
int dist[N];
int h[N], e[M], w[M], ne[M], idx;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void spfa()
{
memset(dist, 0x3f, sizeof dist);
queue<int> q;
q.push(1);
dist[1] = 0;
st[1] = true;
while(q.size())
{
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if(dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
if(!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
while(m --)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
spfa();
printf("%d", dist[n]);
return 0;
}