結果
問題 | No.1002 Twotone |
ユーザー | IKyopro |
提出日時 | 2020-03-29 17:26:08 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2,185 ms / 5,000 ms |
コード長 | 4,200 bytes |
コンパイル時間 | 2,933 ms |
コンパイル使用メモリ | 242,808 KB |
実行使用メモリ | 84,488 KB |
最終ジャッジ日時 | 2024-06-10 19:24:08 |
合計ジャッジ時間 | 26,739 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 1 ms
6,812 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 505 ms
42,900 KB |
testcase_04 | AC | 767 ms
54,800 KB |
testcase_05 | AC | 764 ms
54,756 KB |
testcase_06 | AC | 2 ms
6,944 KB |
testcase_07 | AC | 354 ms
34,508 KB |
testcase_08 | AC | 687 ms
54,708 KB |
testcase_09 | AC | 673 ms
54,784 KB |
testcase_10 | AC | 2 ms
6,940 KB |
testcase_11 | AC | 785 ms
43,096 KB |
testcase_12 | AC | 1,292 ms
54,812 KB |
testcase_13 | AC | 1,217 ms
54,676 KB |
testcase_14 | AC | 2 ms
6,940 KB |
testcase_15 | AC | 459 ms
32,848 KB |
testcase_16 | AC | 1,245 ms
54,864 KB |
testcase_17 | AC | 1,284 ms
54,792 KB |
testcase_18 | AC | 2 ms
6,944 KB |
testcase_19 | AC | 1,038 ms
51,564 KB |
testcase_20 | AC | 1,304 ms
64,120 KB |
testcase_21 | AC | 1,512 ms
63,616 KB |
testcase_22 | AC | 2 ms
6,944 KB |
testcase_23 | AC | 841 ms
43,692 KB |
testcase_24 | AC | 1,908 ms
67,964 KB |
testcase_25 | AC | 1,906 ms
67,964 KB |
testcase_26 | AC | 2 ms
6,944 KB |
testcase_27 | AC | 133 ms
54,080 KB |
testcase_28 | AC | 239 ms
77,436 KB |
testcase_29 | AC | 212 ms
77,696 KB |
testcase_30 | AC | 1 ms
5,376 KB |
testcase_31 | AC | 211 ms
76,996 KB |
testcase_32 | AC | 231 ms
77,560 KB |
testcase_33 | AC | 214 ms
77,544 KB |
testcase_34 | AC | 2,185 ms
84,488 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; template <class T, class U> using Pa = pair<T, U>; template <class T> using vec = vector<T>; template <class T> using vvec = vector<vec<T>>; struct edge{ int to; ll dist,col; edge(int to,ll dist,ll col):to(to),dist(dist),col(col){}; }; class CentroidDecomposition{ public: int N; vvec<edge> g; vec<int> size; vec<int> used; CentroidDecomposition(int N,vvec<edge> tree): N(N),g(tree){ size = used = vec<int>(N,0); } int calc_size(int cur,int par){ int c = 1; for(auto& x:g[cur]){ if(x.to==par || used[x.to]) continue; c += calc_size(x.to,cur); } return size[cur] = c; } //tは連結成分の大きさ //cur以下のうち、削除して残る最大の部分木の大きさを返す Pa<int,int> search_centroid(int cur,int par,int cmp_size){ Pa<int,int> res = {1e9,-1}; int s = 1,ma = 0; for(auto& x:g[cur]){ if(x.to==par || used[x.to]) continue; res = min(res,search_centroid(x.to,cur,cmp_size)); ma = max(ma,size[x.to]); s += size[x.to]; } //子と親の部分木の大きい方 ma = max(ma,cmp_size-s); res = min(res,{ma,cur}); return res; } void dfs(int cur,int par,ll d){ for(auto& e:g[cur]) if(e.to!=par && !used[e.to]){ dfs(e.to,cur,d+e.dist); } } int build(int v){ calc_size(v,-1); int centroid = search_centroid(v,-1,size[v]).second; used[centroid] = true; return centroid; } void disable(int v){used[v] = true;} bool is_alive(int v){return !used[v];} }; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N,K; cin >> N >> K; vvec<edge> g(N); for(int i=0;i<N-1;i++){ int a,b; ll c; cin >> a >> b >> c; a--; b--; g[a].push_back({b,1,c}); g[b].push_back({a,1,c}); } CentroidDecomposition CD(N,g); queue<int> Q; ll ans = 0; Q.push(0); while(!Q.empty()){ int c = CD.build(Q.front()); Q.pop(); map<ll,ll> S,Sp; map<Pa<ll,ll>,ll> D; int n = g[c].size(); vec<map<ll,ll>> Sv(n),Spv(n); vec<map<Pa<ll,ll>,ll>> Dv(n); ll cnt1 = 0; auto dfs = [&](auto&& self,int cur,int par,int id,int c1=-1,int c2=-1)->void{ assert(c1!=c2); // cerr << "centroid : " << c << " cur : " << cur << "\n"; if(c1!=-1 && c2==-1){ S[c1]++; Sv[id][c1]++; cnt1++; } if(c1!=-1 && c2!=-1){ D[minmax({c1,c2})]++; Sp[c1]++; Sp[c2]++; Dv[id][minmax({c1,c2})]++; Spv[id][c1]++; Spv[id][c2]++; ans++; } for(auto& e:g[cur]) if(e.to!=par && CD.is_alive(e.to)){ if(c2==-1){ if(c1!=e.col) self(self,e.to,cur,id,c1,e.col); else self(self,e.to,cur,id,c1,c2); }else{ if(c1==e.col || c2==e.col) self(self,e.to,cur,id,c1,c2); } } }; for(int i=0;i<n;i++){ edge& e = g[c][i]; if(CD.is_alive(e.to)){ dfs(dfs,e.to,-1,i,e.col,-1); Q.push(e.to); } } ll res1 = 0,res2 = 0,res3 = 0; for(int i=0;i<n;i++){ ll sum = 0; for(auto& x:Sv[i]) sum += x.second; for(auto& x:Sv[i]){ res1 += x.second*(cnt1-S[x.first]-(sum-x.second)); } for(auto& x:Dv[i]){ res2 += x.second*(S[x.first.first]-(sum-Sv[i][x.first.first])); res2 += x.second*(S[x.first.second]-(sum-Sv[i][x.first.second])); res3 += x.second*(D[x.first]-x.second); } } // cerr << c << " " << ans << " " << res1 << " " << res2 << " " << res3 << "\n"; ans += res1/2+res2+res3/2; } cout << ans << "\n"; }