记录编号 366182 评测结果 AAAAAAAAAA
题目名称 [POJ1741][男人八题]树上的点对 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 0.642 s
提交时间 2017-01-23 09:07:04 内存使用 0.70 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=10010;
void solve(int,int);
void dfs_getcenter(int,int,int&);
void dfs_getdis(int);
int calc(int*);
vector<int>G[maxn],W[maxn];
int size[maxn],son[maxn],p[maxn],d[maxn];
int a[maxn],b[maxn];
bool vis[maxn]={false};
int n,k,x,y,z,ans;
int main(){
	freopen("poj1741_tree.in","r",stdin);
	freopen("poj1741_tree.out","w",stdout);
	while(scanf("%d%d",&n,&k)==2&&n&&k){
		fill(vis,vis+n+1,false);
		ans=0;
		for(int i=1;i<=n;i++){
			G[i].clear();
			W[i].clear();
		}
		for(int i=1;i<n;i++){
			scanf("%d%d%d",&x,&y,&z);
			G[x].push_back(y);
			W[x].push_back(z);
			G[y].push_back(x);
			W[y].push_back(z);
		}
		solve(1,n);
		printf("%d\n",ans);
	}
	return 0;
}
void solve(int x,int s){
	int u=0;
	dfs_getcenter(x,s,u);
	vis[x=u]=true;
	a[a[0]=1]=0;
	for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]){
		d[G[x][i]]=W[x][i];
		p[G[x][i]]=0;
		b[0]=0;
		dfs_getdis(G[x][i]);
		ans-=calc(b);
		for(int i=1;i<=b[0];i++)a[++a[0]]=b[i];
	}
	ans+=calc(a);
	for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]])solve(G[x][i],size[G[x][i]]);
}
void dfs_getcenter(int x,int s,int &u){
	size[x]=1;
	son[x]=0;
	for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){
		p[G[x][i]]=x;
		dfs_getcenter(G[x][i],s,u);
		size[x]+=size[G[x][i]];
		if(size[G[x][i]]>size[son[x]])son[x]=G[x][i];
	}
	if(!u||max(s-size[x],size[son[x]])<max(s-size[u],size[son[u]]))u=x;
}
void dfs_getdis(int x){
	b[++b[0]]=d[x];
	size[x]=1;
	for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&G[x][i]!=p[x]){
		p[G[x][i]]=x;
		d[G[x][i]]=d[x]+W[x][i];
		dfs_getdis(G[x][i]);
		size[x]+=size[G[x][i]];
	}
}
int calc(int *a){
	sort(a+1,a+a[0]+1);
	int ans=0,i=1,j=a[0];
	while(i<j){
		while(j>i&&a[i]+a[j]>k)j--;
		ans+=j-i;
		i++;
	}
	return ans;
}