这个题目如果看清楚题意就很简单了,然而我还是出了一个非常讨厌的bug,找了半个多小时。
题目意思是给你一张图,求最短路,然后问你如果我要求出两点之间的最短路,那么最坏要枚举到第几个点。
比如说 1-4- 2 -5 我要求1到5的最短路,是不是要枚举到4 这个点才可以求出来。
然后我们就令d[1][5]=4
这个因为n,m都比较小,所以可以之间跑n次最短路,然后每次跑的时候记录一下到这个点前的最大的点的序号。
我的bug在读入,读入的时候我只读了n条边,然后就不断的runtime error 应该要读m条边
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #include <iostream> #include <string> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; const int maxn = 1e5 + 10; const int mod = 998244353; typedef long long ll; ll d[maxn], num[maxn]; int n, m; bool vis[maxn]; struct edge { ll from, to, dist, nxt; edge(ll from = 0, ll to = 0, ll dist = 0, ll nxt = 0) :from(from), to(to), dist(dist), nxt(nxt) {} }ex[maxn]; struct heapnode { ll d, u; heapnode(ll d = 0, ll u = 0) : d(d), u(u) {} bool operator<(const heapnode &a) const { return a.d < d; } }; ll head[maxn], cnt = 0; void init() { memset(head, -1, sizeof(head)); cnt = 0; } void add(ll u, ll v, ll w) { ex[cnt] = edge(u, v, w, head[u]); head[u] = cnt++; ex[cnt] = edge(v, u, w, head[v]); head[v] = cnt++; } void dijkstra(int s) { priority_queue<heapnode>que; while (!que.empty()) que.pop(); memset(d, inf64, sizeof(d)); d[s] = 0, num[s] = 0; memset(vis, 0, sizeof(vis)); que.push(heapnode(0, s)); while (!que.empty()) { heapnode x = que.top(); que.pop(); ll u = x.u; if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i != -1; i = ex[i].nxt) { edge &e = ex[i]; if (d[e.to] == d[u] + e.dist) num[e.to] = min(num[e.to], max(num[u], u)); if (d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; num[e.to] = max(num[u], u); if (u == s) num[e.to] = 0; que.push(heapnode(d[e.to], e.to)); } } } } int main() { int t; scanf("%d", &t); while (t--) { init(); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { ll u, v, w; scanf("%I64d%I64d%I64d", &u, &v, &w); add(u, v, w); } ll ans = 0; for (int i = 1; i <= n; i++) { dijkstra(i); for (int j = 1; j <= n; j++) { ans += num[j];; ans %= mod; } } printf("%I64d ", ans); } return 0; }