Luo Gu P4178 Tree

Partition considered point, for a sub-tree, the root obtains the distance to each point and sorting, dual scan pointer, but this path will be the same from a son count up, and then do it again for each son, Save go to.

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=40005;
char rB[1<<21],*S,*T;
inline char gc(){return S==T&&(T=(S=rB)+fread(rB,1,1<<21,stdin),S==T)?EOF:*S++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int G[N],to[N<<1],w[N<<1],nxt[N<<1],cnt=0,sz[N],f[N],sum,rt,d[N],t[N],tot,k;
ll ans=0ll;
bool vis[N],inq[N];
queue<int> Q;
inline void add(int u,int v,int c){
    to[++cnt]=v;w[cnt]=c;nxt[cnt]=G[u];G[u]=cnt;
    to[++cnt]=u;w[cnt]=c;nxt[cnt]=G[v];G[v]=cnt;
}
void GETRT ( int U, int FA) {   // point focus search partition 
    int I, V;
    sz[u]=1;f[u]=0;
    for(i=G[u];i;i=nxt[i])if(!vis[v=to[i]]&&v!=fa){
        getrt (v, u);
        c [u] + = c [v];
        f[u]=max(f[u],sz[v]);
    }
    f[u]=max(f[u],sum-sz[u]);
    if(f[u]<f[rt])rt=u;
}
ll inline calc ( you and, you k) {
     you i, h, v, l, r;
    ll ans=0ll;
    memset(inq,0,sizeof(inq));
    inq[u]=1;t[tot=1]=d[u]=0;Q.push(u);
    while(!Q.empty()){
        H = Q.front (); Q.pop ();
         for (I = G [H]; I; I = NXT [I]) IF (VIS [to V = [I]] && INQ [V]!! && (D [V] D = [H] + W [I]) <= k) {   // is greater than the distance k is not contribute answers, without saving 
            T [TOT ++] = D [V];
            inq [v] = 1 ;
            Q.push(v);
        }
    }
    sort(t+1,t+tot+1);
    for(l=1,r=tot;l<=r;++l){
        while(l<=r&&t[l]+t[r]>k)--r;
        if(l>r)break;
        years + = r l;
    }
    return years;
}
void solve(int u){
    int i,v;
    vis[u]=1;ans+=calc(u,k);
    for(i=G[u];i;i=nxt[i])if(!vis[v=to[i]]){
        ans - calc = (v, k (in [i] << 1 ));
        sum=sz[v];rt=0;getrt(v,u);
        solve(rt);
    }
}
int main(){
    int n=f[0]=sum=rd(),i,u,v,c;
    for(i=1;i<n;++i){
        u = rd (); v = rd (); c = rd ();
        add(u,v,c);
    }
    k = rd ();
    getrt(1,0);solve(rt);
    printf("%lld",ans);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/sunshine-chen/p/11258752.html