点分治模板 POJ 1741

#include
#include
#include
using namespace std;
const int maxn=1e6+5;
struct asd{
	int from,to,next,val;
}b[maxn];
int head[maxn],tot=1;
void ad(int aa,int bb,int cc){
	b[tot].from=aa;
	b[tot].to=bb;
	b[tot].val=cc;
	b[tot].next=head[aa];
	head[aa]=tot++;
}
int n,k,ans,Tsiz,Root;
int siz[maxn],wt[maxn],a[maxn];
bool vis[maxn];
int cnt;
void get_root(int now,int fa){
	siz[now]=1;
	wt[now]=0;
	for(int i=head[now];i!=-1;i=b[i].next){
		int u=b[i].to;
		if(vis[u] || u==fa) continue;
		get_root(u,now);
		siz[now]+=siz[u];
		wt[now]=max(wt[now],siz[u]);
	}
	wt[now]=max(wt[now],Tsiz-siz[now]);
	if(wt[Root]>wt[now]) Root=now;
	//printf("Root=%d\n",Root);
}
void dfs(int now,int fa,int d){
	a[++cnt]=d;
	//printf("%d %d\n",now,a[cnt]);
	for(int i=head[now];i!=-1;i=b[i].next){
		int u=b[i].to;
		//printf("%d %d\n",now,cnt);
		if(u!=fa && !vis[u]) dfs(u,now,d+b[i].val);
	}
}
int js(int now,int d){
	cnt=0;
	dfs(now,0,d);
	sort(a+1,a+cnt+1);
	/*for(int i=1;i<=cnt;i++){
		printf("%d %d\n",now,a[i]);
	}*/
	//printf("now=%d cnt=%d\n",now,cnt);
	int sum=0;
	for(int i=1,j=cnt;;i++){
		//printf("now=%d a[%d]=%d a[%d]=%d\n",now,i,a[i],j,a[j]);
		while(j && a[i]+a[j]>k) j--;
		if(i>j) break;
		sum+=j-i+1;
	}
	//printf("sum=%d\n",sum);
	return sum;
}
void dfss(int now){
	//printf("ans=%d\n",ans);
	ans+=js(now,0);
	vis[now]=1;
	for(int i=head[now];i!=-1;i=b[i].next){
		int u=b[i].to;
		if(!vis[u]){
			ans-=js(u,b[i].val);
			Root=0;
			Tsiz=siz[u];
			get_root(u,0);
			dfss(Root);
		}
	}
}
int main(){
	while(scanf("%d%d",&n,&k)!=EOF && n){
		ans=0;
		tot=1;
		memset(head,-1,sizeof(head));
		memset(&b,0,sizeof(struct asd));
		memset(vis,0,sizeof(vis));
		for(int i=1;i

你可能感兴趣的:(点分治模板 POJ 1741)