Title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=3365
Problem of point division and treatment
(For Point Division beginners, a simple summary of point Division): Point division by recursive way to find the center of gravity of the subtree, and then the current subtree of the center of gravity as the root, statistics the subtree of all points to the root (center of gravity) of the distance and put into an array, and then do something in the distance array. The time complexity of point division is nlogn* (the time complexity of things done with distance arrays)
The center of gravity of the tree: Find a point to make it a root, with the smallest number of nodes of its maximum subtree
Say this problem: point division to the naked problem, the distance array after sorting with a double pointer L,ro (n) scan, for each L, how many l<i<=r make len[i]+len[l]<=k, the final output answer ( Because this practice of point splitting will have two distances in the same subtree being computed into the answer, the answer to all its subtrees is removed
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <
Algorithm> using namespace std;
const int inf=1e9+7;
const int n=80005;
const int m=160005;
int maxn,siz[n],s[n],dis[n];
int n,m,k,cnt,g,sum,ans,h,lj[n],nxt[m],w[m],to[m];
BOOL Vis[n]; void ins (int f,int t,int p) {cnt++,to[cnt]=t,nxt[cnt]=lj[f],lj[f]=cnt,w[cnt]=p;} void Add (int f,int t,int p) {ins (f,t,p),
Ins (t,f,p);}
void findg (int x,int fa) {siz[x]=1;
int mx=0;
for (int i=lj[x];i;i=nxt[i]) if (To[i]!=fa&&!vis[to[i]]) {FINDG (to[i],x);
Siz[x]+=siz[to[i]];
Mx=max (Mx,siz[to[i]);
} mx=max (Mx,sum-siz[x]);
if (MX<MAXN) maxn=mx,g=x;
} void Dfs (int x,int fa) {s[++h]=dis[x];
for (int i=lj[x];i;i=nxt[i]) if (To[i]!=fa&&!vis[to[i]]) {dis[to[i]]=dis[x]+w[i];
DFS (TO[I],X);
}} int cal (int x,int now) {Dis[x]=now;
h=0;
DFS (x,0);
Sort (s+1,s+h+1);
int ans=0,l=1,r=h; WhilE (l<r) {if (s[l]+s[r]<=k) ans+=r-l,l++;
else r--;
} return ans;
} void solve (int x) {ans+=cal (x,0);
Vis[x]=1;
for (int i=lj[x];i;i=nxt[i]) if (!vis[to[i]]) {ans-=cal (to[i],w[i]);
g=0;
Maxn=inf;
Sum=siz[to[i]];
FINDG (to[i],0);
Solve (G);
}} int main () {scanf ("%d%d", &n,&m);
int u,v,w;
Char ss[5];
for (int i=1;i<=m;i++) {scanf ("%d%d%d%s", &U,&V,&W,&SS);
Add (U,V,W);
} scanf ("%d", &k);
g=0;
Sum=n,maxn=inf;
FINDG (1,0);
Solve (G);
printf ("%d\n", ans);
}