点分治

看懂了。照着hzw(%打了一遍

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define adde(u,v,d) add(u,v,d),add(v,u,d)
#define qwq(x) for(node *o=head[x];o;o=o->next)
int read(){
	int x=0;char c=getchar();bool f=true;
	while(!isdigit(c)){
		if(c=='-') f=false;c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
const int nmax=10005;
const int inf=0x7f7f7f7f;
struct node{
	int to,d;node*next;
};
node e[nmax<<1],*pt=e,*head[nmax];
int f[nmax],deep[nmax],d[nmax],son[nmax];
bool vis[nmax];
int sum,n,k,ans,root;
void add(int u,int v,int d){
	pt->to=v;pt->d=d;pt->next=head[u];head[u]=pt++;
}
void getroot(int x,int fa){
	son[x]=1;f[x]=0;
	qwq(x){
		if(o->to!=fa&&!vis[o->to]){
			getroot(o->to,x);son[x]+=son[o->to];
			f[x]=max(f[x],son[o->to]);
		}
	}
	f[x]=max(f[x],sum-son[x]);
	if(f[x]<f[root]) root=x;
}
void getdeep(int x,int fa){
	deep[++deep[0]]=d[x];
	qwq(x){
		if(o->to!=fa&&!vis[o->to]){
			d[o->to]=d[x]+o->d;getdeep(o->to,x);
		}
	}
}
int cal(int x,int now){
	d[x]=now;deep[0]=0;
	getdeep(x,0);sort(deep+1,deep+deep[0]+1);
	int tmp=0;
	for(int l=1,r=deep[0];l<r;){
		if(deep[l]+deep[r]<=k) tmp+=r-l,l++;
		else r--;
	}
	return tmp;
}
void work(int x){
	ans+=cal(x,0);vis[x]=1;
	qwq(x){
		if(vis[o->to]) continue;
		ans-=cal(o->to,o->d);
		sum=son[o->to];root=0;
		getroot(o->to,root);work(root);
	}
}
int main(){
	while(1){
		n=read(),k=read();if(n==0) break;
		clr(vis,0);clr(head,0);ans=root=0;pt=e;
		rep(i,n-1){
			int s=read(),t=read(),w=read();adde(s,t,w);
		}
		sum=n;f[0]=inf;getroot(1,0);work(root);
		printf("%d\n",ans);
	}
	return 0;
}

 

posted @ 2016-07-04 20:17  BBChq  阅读(134)  评论(0编辑  收藏  举报