这题大意是给你一棵树,然后如果u和v共用一个点w,那么u和v之间也连一条边,问所有对点之间的距离和是多少。
这题画画图以后可以得出:树上偶数距离的点在加边以后的距离等于距离/2,树上奇数距离的点在加边以后的距离等于距离/2+1。所以加边以后的答案等于(原树上的距离+两点之间距离为奇数的对数)/2。
原树上的距离直接dfs就行,这个两点之间距离为奇数的对数没想到,答案应该是距离root为偶数的点乘距离为奇数的点,算是一个小trick吧
还有一个点:(x1+1)/2+(x2+1)/2=(x1+x2+x1%2+x2%2)/2
#include<bits/stdc++.h>
using namespace std;
using LL = int64_t;
const int maxn=2e5+5;
vector<int>E[maxn];
LL sz[maxn];
LL sum0=0,sum1=0,ans=0;
void dfs(int x,int fa,int level) {
if(level%2==1) sum1++;
else sum0++;
sz[x]++;
for(auto it:E[x]) {
if(it==fa) continue;
dfs(it,x,level+1);
sz[x]+=sz[it];
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
LL n;cin>>n;
for(int i=1;i<n;i++) {
int u,v;cin>>u>>v;
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1,0,0);
ans=sum1*sum0;
for(int i=1;i<=n;i++) {
ans=ans+sz[i]*(n-sz[i]);
}
cout<<ans/2;
return 0;
}