結果
問題 | No.1002 Twotone |
ユーザー | IKyopro |
提出日時 | 2020-03-29 17:01:46 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,011 bytes |
コンパイル時間 | 3,259 ms |
コンパイル使用メモリ | 242,264 KB |
実行使用メモリ | 90,248 KB |
最終ジャッジ日時 | 2024-06-10 19:21:19 |
合計ジャッジ時間 | 29,381 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | AC | 2 ms
6,944 KB |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | AC | 2 ms
6,940 KB |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
testcase_25 | WA | - |
testcase_26 | AC | 2 ms
6,940 KB |
testcase_27 | AC | 157 ms
60,804 KB |
testcase_28 | AC | 301 ms
90,248 KB |
testcase_29 | AC | 261 ms
90,240 KB |
testcase_30 | AC | 2 ms
6,944 KB |
testcase_31 | AC | 242 ms
89,888 KB |
testcase_32 | AC | 305 ms
89,976 KB |
testcase_33 | AC | 260 ms
89,852 KB |
testcase_34 | WA | - |
ソースコード
#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); 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(c1==-1) self(self,e.to,cur,id,e.col,c2); else 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)); res2 += x.second*(Sp[x.first]-Spv[i][x.first]); } for(auto& x:Dv[i]){ res3 += x.second*(D[x.first]-x.second); } } ans += res1/2+res2/4+res3/2; } cout << ans << "\n"; }