[ABC312G] Avoid Straight Line 题解
前言
纪念自己第二次做出 ABC 的 G!
解法
显然的一个树形 DP。
令
正难则反,考虑有多少个
为方便理解,我们将
这里
把所有点的贡献加起来,记为
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n,s=0; cin>>n;
vector<int> e(n),f(n);
vector<vector<int> > g(n);
for(int i=1;i<n;i++){
int u,v; cin>>u>>v;
g[--u].emplace_back(--v);
g[v].emplace_back(u);
}
function<void(int,int)> dfs=[&](int u,int f){
e[u]=1;
for(int i:g[u])
if(i!=f)dfs(i,u),e[u]+=e[i];
};
dfs(0,0);
function<void(int,int)> dfs2=[&](int u,int f){
int c=0,c2=0;
for(int i:g[u])
if(i==f)c+=n-e[u],c2+=(n-e[u])*(n-e[u]);
else dfs2(i,u),c+=e[i],c2+=e[i]*e[i];
s+=c*c-c2>>1;
};
dfs2(0,0);
cout<<n*(n-1)*(n-2)/6-s<<endl;
return 0;
}