我使用 Dijkstra O(mnlogm) 的思路 AC 后(AC 代码见下方)在 dijkstra 函数里的 ... 处添加了一句 if (vis[i.to] && dist[i.to] < ndist) exit(0);,即 如果正在尝试松弛的节点已经被访问过 且无法被松弛,那么直接退出程序。这样的情况显然是不存在的。但是提交之后,直接 TLE。
也就是说在代码中凭空添加了一个不可能进入的分支,导致用时直接增加 300ms。有人能解释嘛
加了exit(0),但把if里的两个条件换了个顺序,虽然相比啥都不加有点慢但是 AC 了
加了 if,但把exit(0)的位置换成了一个无关紧要的变量++,竟然也 AC 了,还挺快
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#ifdef ONLINE_JUDGE
constexpr int N = 2e3 + 5;
constexpr int M = 2e5 + 5;
#else
constexpr int N = 2e3 + 5;
constexpr int M = 2e5 + 5;
#endif
constexpr int INF = 0x3F3F3F3F;
struct Edge {
int u, v;
} e[M];
struct Edge2 {
int to, id;
};
vector<Edge2> a[N], b[N];
int n, m;
int dist_a[N], dist_b[N];
bool vis[N];
struct Node {
int id, dist;
};
bool operator < (Node x, Node y) {
return x.dist < y.dist;
}
template<vector<Edge2> *g, int *dist>
inline void dijkstra(const int bg) {
memset(dist, 0, (n + 1) << 2);
memset(vis, false, (n + 1));
priority_queue<Node> heap;
heap.push({bg, INF});
dist[bg] = INF;
while (!heap.empty()) {
auto t = heap.top();
heap.pop();
if (vis[t.id])
continue;
vis[t.id] = true;
for (auto i : g[t.id]) {
if (i.to < bg)
continue;
const int ndist = min(dist[t.id], i.id);
/*
... ... ...
*/
if (dist[i.to] < ndist) {
dist[i.to] = ndist;
heap.push({i.to, ndist});
}
}
}
}
int suf[M];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
a[u].push_back({v, i});
b[v].push_back({u, i});
}
for (int i = 1; i <= n; i++) {
dijkstra<a, dist_a>(i);
dijkstra<b, dist_b>(i);
for (int j = i + 1; j <= n; j++)
suf[min(dist_a[j], dist_b[j])]++;
}
suf[m + 1] = n;
for (int i = m; i >= 1; i--)
suf[i] += suf[i + 1];
for (int i = 1; i <= m + 1; i++)
cout << suf[i] << ' ';
return 0;
}