地址 https://www.acwing.com/problem/content/description/852/
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为非负值。 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。 输入格式 第一行包含整数n和m。 接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。 输出格式 输出一个整数,表示1号点到n号点的最短距离。 如果路径不存在,则输出-1。 数据范围 1≤n,m≤105, 图中涉及边长均不小于0,且不超过10000
输入样例: 3 3 1 2 2 2 3 1 1 3 4 输出样例: 3
这里相比上一篇 Dijkstra模板 使用了堆记录点距离 从而节省了查找最短距离的开销
#include <iostream> #include <vector> #include <queue> #include <memory.h> using namespace std; typedef pair<int, int> PII; const int N = 100010; vector<vector<pair<int, int>>> gra; int dist[N]; int st[N]; int n, m; int solve() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; //这里是距离在前 节点号在后 priority_queue<PII, vector<PII>, greater<PII>> heap; heap.push({ 0, 1 }); // first存储距离,second存储节点编号 while (heap.size()) { auto t = heap.top(); heap.pop(); int node = t.second; int distance = t.first; if (st[node]) continue; st[node] = true; //查看每个出边 for (int i = 0; i < gra[node].size(); i++) { int newnode = gra[node][i].first; int len = gra[node][i].second; if (dist[newnode] > dist[node] + len) { dist[newnode] = dist[node] + len; heap.push({ dist[newnode],newnode }); } } } if (dist[n] == 0x3f3f3f3f) return -1; return dist[n]; } int main() { //cin >> n >> m; scanf("%d %d",&n,&m); gra.resize(n + 1); for (int i = 0; i < m; i++) { int a, b, c; //cin >> a >> b >> c; scanf("%d %d %d",&a,&b,&c); //这里是 目的节点号在前 边长在后 gra[a].push_back({ b,c }); } printf("%d ", solve() ); return 0; }