ベスパリブ

プログラミングを主とした日記・備忘録です。ベスパ持ってないです。

ABC292 E - Transitivity のTLE解

概要

ABC292 E - Transitivity の解法で、辺を管理するデータ構造をsetにするとTLEした。

setforでアクセスするとTLEすることはあったが、count()insert() の 対数時間でTLEしたのは初めて。

解法とコード

「既存の辺(u,v)をすべてdequeに突っ込む。dequeから辺(u,v)を取り出し、辺(v,w)のうちまだ(u,w)に辺が無いなら、deque(u,w)を追加して答えを+1する。dequeが空になるまで繰り返す」という解き方をした。

辺を管理するデータをg[i][j] := iからjへ辺があるとする。

ここで辺を管理するデータ構造をset<pair<ll,ll>> edgeSetにするとTLEするので注意。

bitsetを使えばもっと早い。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    ll N, M; cin >> N >> M;
    vector G(N, vector<ll>());
    // set<pair<ll,ll>> edgeSet; // TLE
    // vector<bitset<2000>> g(N); // g[i][j] := iからjへ辺がある // AC
    vector g(N, vector(N, false)); // g[i][j] := iからjへ辺がある // AC
    deque<pair<ll,ll>> deq; // (u,v)
    for(ll i=0; i<M; i++) {
        ll u, v; cin >> u >> v;
        u--; v--;
        G[u].push_back(v);
        // edgeSet.insert({u,v});
        // g[u].set(v, 1);
        g[u][v] = true;
        deq.push_back({u,v});
    }

    ll ans = 0;
    while(!deq.empty()) {
        auto[u, v] = deq.front(); deq.pop_front();

        // vからwへの辺があるとき、uからwへの辺はあるか?
        for(ll w: G[v]) {
            if (u == w) continue;
            // if (!edgeSet.count({u,w})) {
            if (!g[u][w]) {
                // edgeSet.insert({u,w});
                // g[u].set(w, 1);
                g[u][w] = true;
                ans++;
                deq.push_back({u,w});
            }
        }
    }
    cout << ans << endl;
}


int main() {
    solve();
    return 0;
}