码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1741 点分治

时间:2018-09-26 22:10:16      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:cond   +=   pre   cal   oid   sort   两个指针   ret   --   

方法:指针扫描数组

每次选择树的重心作为树根,从树根出发进行一次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\n",dfs(1));
	}
}
//5 1
//1 2 1
//2 3 1
//3 4 1
//4 5 1

 

POJ 1741 点分治

标签:cond   +=   pre   cal   oid   sort   两个指针   ret   --   

原文地址:https://www.cnblogs.com/pkgunboat/p/9709941.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!