一个计数问题,下次看到数据就直接dp吧.有点分治思想在里面.
就是一个点一个点的计数,一条链一条链的来,f[i][j]表示到了i这个点值为j的方案数...如此转移下就好了.
#include <bits/stdc++.h> using namespace std; const int N=2e4+5,M=2e3+2e2; int f[N][M]; struct vv{ int to,val; }; vector<vv>v[N]; int ans=0; void dfs(int u,int fa) { for(int i=0;i<2019;i++) f[u][i]=0; f[u][0]=1; for(int i=0;i<v[u].size();i++) { int x=v[u][i].to;int val=v[u][i].val; if(x==fa) continue; dfs(x,u); for(int j=0;j<2019;j++) { ans+=f[u][j]*f[x][(4038-val-j)%2019]; } for(int j=0;j<2019;j++) { f[u][(j+val)%2019]+=f[x][j]; } } } int main() { int n; while(scanf("%d",&n)!=EOF) { ans=0; for(int i=1;i<=n;i++) v[i].clear(); for(int i=1;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); v[x].push_back({y,z}); v[y].push_back({x,z}); } dfs(1,-1); printf("%d\n",ans); } return 0; }