题目链接:三角果计数 - 题目 - Daimayuan Online Judge
视频题解:【算法camp】【每日一题】Namomo Spring Camp Div1 第17天题解(动态规划、容斥)dls讲题!!_哔哩哔哩_bilibili
思路:理解题意之后手算一下发现,三点只要不连成一线,那就一定是三角果。考虑用总数C(n,3)减去不合题意的情况(三点一线的情况)。用树形dp计算三点一线的情况,注意重复计数,结果要/2。?
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
const int N = 1e5+5;
int n,ans=0;
vector<int> g[N];
inline int Cn3(int x){return x*(x-1)*(x-2)/6;}
int dfs(int u,int fa){
int sz=1; //当前子树大小
int rest=n-1, sum=n-1;
for(int v:g[u]){
if(v==fa) continue;
int cur=dfs(v,u); //当前子树大小
sz+=cur; rest-=cur;
ans+=cur*(sum-cur);
}
ans+=rest*(sum-rest);
return sz;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin>>n; int x,y,w;
FOR(i,1,n-1){
cin>>x>>y>>w;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,0);
cout<<Cn3(n)-ans/2;
}
|