結果
問題 | No.2677 Minmax Independent Set |
ユーザー |
![]() |
提出日時 | 2024-03-20 12:38:42 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 109 ms / 2,000 ms |
コード長 | 5,005 bytes |
コンパイル時間 | 2,932 ms |
コンパイル使用メモリ | 259,836 KB |
実行使用メモリ | 53,956 KB |
最終ジャッジ日時 | 2024-09-30 06:03:19 |
合計ジャッジ時間 | 8,024 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 61 |
ソースコード
#include <bits/stdc++.h>using namespace std;//#include <atcoder/all>//using namespace atcoder;//using mint = modint998244353;//多倍長整数////#include <boost/multiprecision/cpp_int.hpp>//namespace mp = boost::multiprecision;//using Bint = mp::cpp_int;const int INF = 1e9;const int MOD = 998244353;const long long LINF = 4e18;using ll = long long;using vi = vector<int>;using vl = vector<long long>;using vs = vector<string>;using vc = vector<char>;using vb = vector<bool>;using vvi = vector<vector<int>>;using vvvi = vector<vector<vector<int>>>;using vvvvi = vector<vector<vector<vector<int>>>>;using vvl = vector<vector<long long>>;using vvvl = vector<vector<vector<long long>>>;using vvvvl = vector<vector<vector<vector<long long>>>>;using vvc = vector<vector<char>>;using vvb = vector<vector<bool>>;using vvvb = vector<vector<vector<bool>>>;using vvvvb = vector<vector<vector<vector<bool>>>>;#define rep(i, n) for (int i = 0; i < (int)(n); i++)#define dump(x) cout << #x << " = " << (x) << endl;#define Yes(n) cout << ((n) ? "Yes" : "No" ) << endl#define ALL(obj) (obj).begin(),(obj).end()//https://trap.jp/post/1702/template <class E, class V, E (*merge)(E, E), E (*e)(), E (*put_edge)(V, int), V (*put_vertex)(E, int)>struct RerootingDP {struct edge {int to, idx, xdi;};RerootingDP(int n_ = 0) : n(n_), inner_edge_id(0) {es.resize(2*n-2);start.resize(2*n-2);if (n == 1) es_build();}void add_edge(int u, int v, int idx, int xdi){start[inner_edge_id] = u;es[inner_edge_id] = {v,idx,xdi};inner_edge_id++;start[inner_edge_id] = v;es[inner_edge_id] = {u,xdi,idx};inner_edge_id++;if (inner_edge_id == 2*n-2){es_build();}}vector<V> build(int root_ = 0){root = root_;vector<V> subdp(n); subdp[0] = put_vertex(e(),0);outs.resize(n);vector<int> geta(n+1,0);for (int i = 0; i < n; i++) geta[i+1] = start[i+1] - start[i] - 1;geta[root+1]++;for (int i = 0; i < n; i++) geta[i+1] += geta[i];auto dfs = [&](auto sfs, int v, int f) -> void {E val = e();for (int i = start[v]; i < start[v+1]; i++){if (es[i].to == f){swap(es[start[v+1]-1],es[i]);}if (es[i].to == f) continue;sfs(sfs,es[i].to,v);E nval = put_edge(subdp[es[i].to],es[i].idx);outs[geta[v]++] = nval;val = merge(val,nval);}subdp[v] = put_vertex(val, v);};dfs(dfs,root,-1);return subdp;}vector<V> reroot(){vector<E> reverse_edge(n);reverse_edge[root] = e();vector<V> answers(n);auto dfs = [&](auto sfs, int v) -> void {int le = outs_start(v);int ri = outs_start(v+1);int siz = ri - le;vector<E> rui(siz+1);rui[siz] = e();for (int i = siz-1; i >= 0; i--){rui[i] = merge(outs[le+i],rui[i+1]);}answers[v] = put_vertex(merge(rui[0],reverse_edge[v]),v);E lui = e();for (int i = 0; i < siz; i++){V rdp = put_vertex(merge(merge(lui,rui[i+1]),reverse_edge[v]),v);reverse_edge[es[start[v]+i].to] = put_edge(rdp,es[start[v]+i].xdi);lui = merge(lui,outs[le+i]);sfs(sfs,es[start[v]+i].to);}};dfs(dfs,root);return answers;}private:int n, root, inner_edge_id;vector<E> outs;vector<edge> es;vector<int> start;int outs_start(int v){int res = start[v] - v;if (root < v) res++;return res;}void es_build(){vector<edge> nes(2*n-2);vector<int> nstart(n+2,0);for (int i = 0; i < 2*n-2; i++) nstart[start[i]+2]++;for (int i = 0; i < n; i++) nstart[i+1] += nstart[i];for (int i = 0; i < 2*n-2; i++) nes[nstart[start[i]+1]++] = es[i];swap(es,nes);swap(start,nstart);}};pair<int,int> merge(pair<int,int> a,pair<int,int> b){return {a.first + b.first,a.second + b.second};}pair<int,int> e(){return make_pair(0,0);}pair<int,int> put_e(pair<int,int> x,int i){return {x.first,max(x.first,x.second)};}pair<int,int> put_v(pair<int,int> x,int i){return {x.second,x.first + 1};}int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin >> n;RerootingDP<pair<int,int>, pair<int,int>,merge, e,put_e,put_v> dp(n);rep(i,n - 1){int a,b;cin >> a >> b;a--;b--;dp.add_edge(a,b,i,i + n);}int ans = INF;dp.build();auto ret = dp.reroot();// cout << endl;// rep(i,n) cout << ret[i].first << ' ' << ret[i].second << endl;rep(i,n){ans = min(ans,ret[i].second);}cout << ans << endl;return 0;}