poj1741 树分治

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 12000
int e[maxn],v[maxn*2],ne[maxn*2],w[maxn*2];
bool vis[maxn];
int n;
int nn;
void add(int x,int y,int z){
 nn++;
 ne[nn]=e[x];
 e[x]=nn;
 v[nn]=y;
 w[nn]=z;
}
void clear(){
 nn=0;
 memset(vis,0,sizeof(vis));
 memset(e,0,sizeof(e));

}
int tot,a[maxn];
int dist[maxn],siz[maxn];
void dfs1(int x,int fa){
 a[++tot]=dist[x];
 for(int i=e[x];i;i=ne[i]){
    if(v[i]==fa||vis[v[i]])continue;
    dist[v[i]]=dist[x]+w[i];
    dfs1(v[i],x);
 }
}
int cc[maxn],k;
int bn,b[maxn];
void dfs2(int x,int fa){
 siz[x]=1;
 cc[x]=0;
 b[++bn]=x;
 for(int i=e[x];i;i=ne[i]){
     if(fa==v[i]||vis[v[i]])continue;
  dfs2(v[i],x);
  cc[x]=max(cc[x],siz[v[i]]);
  siz[x]+=siz[v[i]];
 }
}
int count(int x,int ma){
 if(ma<=0)return 0;
 tot=0;
 dist[x]=0;
 dfs1(x,0);
 sort(a+1,a+tot+1);
 int bo=tot;
 int res=0;
 for(int i=1;i<=tot;i++){
  while(a[i]+a[bo]>ma&&bo>i)bo--;
  if(bo>i)res+=bo-i;
 }
 return res;
}
int ans;
int pp;
void solv(int x){
 int rt=-1;
 bn=0;
 dfs2(x,0);
 if(bn==1)return;
 for(int i=1;i<=bn;i++){
  cc[b[i]]=max(cc[b[i]],bn-siz[b[i]]);
  if(rt==-1||cc[b[i]]<cc[rt])rt=b[i];
 }
 ans+=count(rt,k);
 vis[rt]=1;
 for(int i=e[rt];i;i=ne[i])if(!vis[v[i]]){
  ans-=count(v[i],k-2*w[i]);
  solv(v[i]);
 }
}
int main(){
 while(scanf("%d%d",&n,&k)&&(n!=0||k!=0)){
  clear();
  ans=0;
  for(int i=1;i<n;i++){
   int a,b,c;
   scanf("%d%d%d",&a,&b,&c);
   add(a,b,c);
   add(b,a,c);
  }
  solv(1);
  printf("%d\n",ans);
 }

}

posted @ 2014-02-20 17:07  wangyucheng  阅读(131)  评论(0编辑  收藏  举报