E-Flower_Rainbow_and_Game_牛客小白月赛127
这个题我们可以先算出所有点对之间的距离 然后将所有含有父子关系的点对的距离减去 然后加1 也就是代价变为1 对于所有点对的距离和 我们可以计算每条边的贡献 每条边被遍历的次数和就是所有点对的距离和 那么对于u 和 v 他们之间的边被遍历的次数就等于size[v]*(n-size[v]) 累加即可
对于所有有父子关系的点 他们的距离和就是 v的所有子节点的深度和-v的子节点的数目*父节点的深度
cpp
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n;cin>>n;
vector<vector<int>>e(n+1);
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
long long ans=0;
vector<int> sz(n+1,1),dep(n+1);
auto dfs=[&](auto &&self,int u,int f)->void{
for(auto v:e[u]){
if(v!=f){
dep[v]=dep[u]+1;
self(self,v,u);
ans+=sz[v]*(n-sz[v]);
sz[u]+=sz[v];
}
}
};
dfs(dfs,1,0);
vector<int>s=dep;
auto dfs2=[&](auto &&self,int u,int p)->void{
for(auto v:e[u]){
if(v!=p){
self(self,v,u);
s[u]+=s[v];
ans-=s[v]-dep[u]*sz[v];
ans+=sz[v];
}
}
};
dfs2(dfs2,1,0);
cout<< ans % 998244353<<'\n';
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}