結果

問題 No.1976 Cut then Connect
ユーザー KudeKude
提出日時 2022-06-10 23:08:50
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 143 ms / 2,000 ms
コード長 3,968 bytes
コンパイル時間 2,264 ms
コンパイル使用メモリ 235,484 KB
実行使用メモリ 34,252 KB
最終ジャッジ日時 2023-08-16 02:41:47
合計ジャッジ時間 5,050 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 2 ms
4,380 KB
testcase_02 AC 127 ms
32,476 KB
testcase_03 AC 58 ms
20,596 KB
testcase_04 AC 19 ms
9,408 KB
testcase_05 AC 46 ms
18,460 KB
testcase_06 AC 85 ms
26,320 KB
testcase_07 AC 49 ms
18,512 KB
testcase_08 AC 132 ms
34,252 KB
testcase_09 AC 111 ms
29,720 KB
testcase_10 AC 22 ms
10,916 KB
testcase_11 AC 142 ms
33,648 KB
testcase_12 AC 4 ms
4,408 KB
testcase_13 AC 87 ms
26,188 KB
testcase_14 AC 79 ms
24,484 KB
testcase_15 AC 77 ms
23,692 KB
testcase_16 AC 115 ms
31,288 KB
testcase_17 AC 32 ms
13,612 KB
testcase_18 AC 7 ms
5,452 KB
testcase_19 AC 85 ms
25,968 KB
testcase_20 AC 143 ms
34,012 KB
testcase_21 AC 68 ms
21,620 KB
testcase_22 AC 2 ms
4,380 KB
testcase_23 AC 1 ms
4,376 KB
testcase_24 AC 1 ms
4,380 KB
testcase_25 AC 1 ms
4,376 KB
testcase_26 AC 1 ms
4,380 KB
testcase_27 AC 1 ms
4,380 KB
testcase_28 AC 1 ms
4,380 KB
testcase_29 AC 1 ms
4,376 KB
testcase_30 AC 1 ms
4,376 KB
testcase_31 AC 2 ms
4,376 KB
testcase_32 AC 2 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic pop
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;

template<class S, class E>
struct Rerooting {
    const vector<vector<E>>& g;
    const int n;
    const int root;
    vector<vector<S>> dp, sl, sr;

    Rerooting(const vector<vector<E>>& g, int root=0): g(g), n(g.size()), root(root), dp(n), sl(n), sr(n) {
        dfs1(root);
        dfs2(root);
    }

    S dfs1(int u, int p=-1) {
        const int sz = g[u].size();
        dp[u].resize(sz);
        sl[u].resize(sz + 1);
        sr[u].resize(sz + 1);

        S res;
        for(int i = 0; i < sz; i++) {
            const E& e = g[u][i];
            int v = dest(e);
            if (v == p) continue;
            dp[u][i] = dfs1(v, u).apply(e);
            res = res.merge(dp[u][i]);
        }
        return res;
    }

    void dfs2(int u, int p=-1) {
        const int sz = g[u].size();

        {
            S s;
            for(int i = 0; i < sz; i++) {
                s = s.merge(dp[u][i]);
                sl[u][i + 1] = s;
            }
        }
        {
            S s;
            for(int i = sz - 1; i >= 0; i--) {
                s = dp[u][i].merge(s);
                sr[u][i] = s;
            }
        }

        for(int i = 0; i < sz; i++) {
            int v = dest(g[u][i]);
            if (v == p) continue;
            const int sz_v = g[v].size();
            for(int j = 0; j < sz_v; j++) {
                const E& e = g[v][j];
                int w = dest(e);
                if (w != u) continue;
                dp[v][j] = sl[u][i].merge(sr[u][i + 1]).apply(e);
                break;
            }
            dfs2(v, u);
        }
    }

    S get_acc(int v) { return sr[v][0]; }
    S get_res(int v, E e) { return sr[v][0].apply(e); }

    private:
    int dest(const E& e) {
        if constexpr (is_same<E, int>::value) return e;
        else return e.to;
    };
};

template<unsigned int k, class V, class Compare=less<V>>
struct Min_k {
  V d[k];
  int size = 0;
  bool add(V v) {
    constexpr Compare cmp;
    for (int i = 0; i < size; i++) {
      if (cmp(v, d[i])) {
        if (size != k) size++;
        for (int j = size - 1; j != i; j--) {
          d[j] = move(d[j - 1]);
        }
        d[i] = move(v);
        return true;
      }
    }
    if (size != k) {
      d[size++] = v;
      return true;
    }
    return false;
  }
  V* begin() { return d; }
  V* end() { return d + size; }
};

struct S {
    int pmx = 0;
    Min_k<2, int, greater<int>> mx{{0, 0}, 2};
    S apply(int) const {
      return {max(pmx, mx.d[0] + mx.d[1]), {{mx.d[0] + 1, 0}, 2}};
    }
    S merge(S& rhs) const {
      auto nmx = mx;
      for(int x: rhs.mx) nmx.add(x);
      return S{ max(pmx, rhs.pmx), nmx};
    }
};

} int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  VVI to(n);
  vector<pair<P, P>> es;
  rep(i, n - 1) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    es.emplace_back(P(u, to[u].size()), P(v, to[v].size()));
    to[u].emplace_back(v);
    to[v].emplace_back(u);
  }
  Rerooting<S, int> rt(to);
  int ans = n;
  for(auto [e1, e2]: es) {
    auto [u, iu] = e1;
    auto [v, iv] = e2;
    int p1 = rt.dp[u][iu].pmx;
    int p2 = rt.dp[v][iv].pmx;
    chmin(ans, max({p1, p2, (p1 + 1) / 2 + (p2 + 1) / 2 + 1}));
  }
  cout << ans << '\n';
}
0