結果
| 問題 |
No.1002 Twotone
|
| コンテスト | |
| ユーザー |
ngtkana
|
| 提出日時 | 2020-02-28 23:36:44 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,751 bytes |
| コンパイル時間 | 2,364 ms |
| コンパイル使用メモリ | 193,880 KB |
| 実行使用メモリ | 64,512 KB |
| 最終ジャッジ日時 | 2024-10-13 19:20:45 |
| 合計ジャッジ時間 | 14,593 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 6 WA * 27 |
ソースコード
#include<bits/stdc++.h>
int main(){
int n,k;std::cin>>n>>k;
std::vector<std::vector<std::pair<int,int>>>g(n);
std::vector<std::vector<int>>member(k);
for(int i=0;i<n-1;i++){
int u,v,c;std::cin>>u>>v>>c;
u--,v--,c--;
g.at(u).emplace_back(v,c);
g.at(v).emplace_back(u,c);
member.at(c).push_back(u);
member.at(c).push_back(v);
}
for(int i=0;i<k;i++){
auto&mem=member.at(i);
std::sort(mem.begin(),mem.end());
mem.resize(std::unique(mem.begin(),mem.end())-mem.begin());
}
auto rev=[&](int c,int u){
auto it=std::lower_bound(member.at(c).begin(),member.at(c).end(),u);
assert(it!=member.at(c).end());
assert(*it==u);
return it-member.at(c).begin();
};
std::vector<std::vector<std::vector<int>>>h(k);
for(int i=0;i<k;i++)h.at(i).resize(member.at(i).size());
for(int i=0;i<n;i++){
for(auto&&e:g.at(i)){
int j,c;std::tie(j,c)=e;
int u=rev(c,i),v=rev(c,j);
h.at(c).at(u).push_back(v);
h.at(c).at(v).push_back(u);
}
}
for(int i=0;i<k;i++){
for(auto&&v:h.at(i)){
std::sort(v.begin(),v.end());
v.resize(std::unique(v.begin(),v.end())-v.begin());
}
}
std::vector<std::vector<long long>>a(n);
for(int i=0;i<k;i++){
auto&mem=member.at(i);
int sz=mem.size();
std::vector<int>ckd(sz,false);
for(int j=0;j<sz;j++){
if(ckd.at(j))continue;
std::vector<int>cmp;
std::queue<int>que;
que.push(j);
ckd.at(j)=true;
while(!que.empty()){
int x=que.front();que.pop();
cmp.push_back(x);
for(int y:h.at(i).at(x)){
if(ckd.at(y))continue;
que.push(y);
ckd.at(y)=true;
}
}
int val=cmp.size()-1;
for(int x:cmp){
a.at(mem.at(x)).push_back(val);
}
}
}
long long ans=0;
for(int i=0;i<n;i++){
long long sum=0,sqsum=0;
for(int x:a.at(i)){
sum+=x;
sqsum+=x*x;
}
ans+=(sum*sum-sqsum)/2;
}
std::cout<<ans<<std::endl;
}
/*
色の変わり目を全探索です。
各頂点から、各色のパスがいくつあるのかを計算です。
すると、相異なるものの積の和ですから、和の二乗から二乗の和を引いて 2 で割ればよいです。
パスの数は、その頂点の属するその色のグラフの連結成分の大きさ - 1 です。
色ごとに別々のグラフを作り、座標圧縮です。
*/
ngtkana