关于运行时长的玄学问题
查看原帖
关于运行时长的玄学问题
402255
Untitled10032楼主2023/8/27 23:31

我使用 Dijkstra O(mnlog⁡m)O(mn\log m) 的思路 AC 后(AC 代码见下方)在 dijkstra 函数里的 ... 处添加了一句 if (vis[i.to] && dist[i.to] < ndist) exit(0);,即 如果正在尝试松弛的节点已经被访问过 且无法被松弛,那么直接退出程序。这样的情况显然是不存在的。但是提交之后,直接 TLE。

也就是说在代码中凭空添加了一个不可能进入的分支,导致用时直接增加 300ms。有人能解释嘛

啥都不加的提交记录,AC

加了上文中的exit(0),TLE

加了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;
}
2023/8/27 23:31
加载中...