POJ 1741 点分治

Posted pkgunboat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1741 点分治相关的知识,希望对你有一定的参考价值。

方法:指针扫描数组

每次选择树的重心作为树根,从树根出发进行一次DFS,求出点到树根的距离,把节点按照与树根的的距离放进数组d,设置两个指针L,R分别从前、后开始扫描,每次满足条件时答案累加R-L。,之后减去子树的满足条件的情况,删除根节点,对其子树继续上述操作,不断累加答案。

代码:

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100010;
vector<pair<int,int> >G[maxn];
int d[maxn],size[maxn],root,max_w,n1,cnt,n,k;
bool vis[maxn];
void get_root(int x,int f){//求树的重心 
	size[x]=1;
	int max_part=0;
	for(int i=0;i<G[x].size();i++){
		int Next=G[x][i].first;
		if(Next!=f&&!vis[Next]){
			get_root(Next,x);
			size[x]+=size[Next];
			max_part=max(max_part,size[Next]);
		}
	}
	max_part=max(max_part,n1-size[x]);
	if(max_part<max_w){
		root=x;
		max_w=max_part;
	}
}
void get_dist(int x,int f,int dist){//算距离 
	d[++cnt]=dist;
	size[x]=1;//算距离的同时也更新一下子树的大小 
	for(int i=0;i<G[x].size();i++){
		int Next=G[x][i].first;
		if(Next!=f&&!vis[Next]){
			get_dist(Next,x,dist+G[x][i].second);
			size[x]+=size[Next];
		}
	}
}
int cal(int x,int y){//计算 
	cnt=0;
	get_dist(x,-1,y);
	sort(d+1,d+1+cnt);
	int ans=0;
	for(int i=1,j=cnt;i<j;i++){
		while(d[i]+d[j]>k&&i<j)j--;
		ans+=j-i;
	}
	return ans;
}
int dfs(int x){//dfs主框架 
	max_w=n1;
	get_root(x,-1);
	int now=root;
	vis[now]=1;
	int ans=0;
	ans+=cal(now,0);
	for(int i=0;i<G[now].size();i++){
		int Next=G[now][i].first;
		if(!vis[Next]){
			ans-=cal(Next,G[now][i].second);
			n1=size[Next];
			ans+=dfs(Next);
		}
	}
	return ans;
}
void init(int n){
	for(int i=1;i<=n;i++)G[i].clear();
	cnt=0;
	memset(vis,0,sizeof(vis));
}
int main(){
	int u,v,dis;
	while(~scanf("%d%d",&n,&k)&&n&&k){
		init(n);
		for(int i=1;i<n;i++){
			scanf("%d%d%d",&u,&v,&dis);
			G[u].push_back(make_pair(v,dis));
			G[v].push_back(make_pair(u,dis));
		}
		n1=n;
		printf("%d
",dfs(1));
	}
}
//5 1
//1 2 1
//2 3 1
//3 4 1
//4 5 1

 

以上是关于POJ 1741 点分治的主要内容,如果未能解决你的问题,请参考以下文章

poj1741(入门点分治)

POJ 1741 点分治

POJ 1741 树分治(点分治模板题)

POJ 1741 Tree(点分治)

POJ - 1741 - Tree - 点分治 模板

poj1741 Tree(点分治)