您的位置:首页 > 其它

POJ 1741 Tree

2015-10-24 16:22 267 查看

Tree

Time Limit: 1000ms
Memory Limit: 30000KB
This problem will be judged on PKU. Original ID: 1741
64-bit integer IO format: %lld Java class name: Main

Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.

Input

The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0

Sample Output

8

Source

LouTiancheng@POJ

解题:点分治。楼教主的男人八题之一。哥的第一道点分治
哎,太恶心了,不说了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100010;
struct arc{
int to,w,next;
arc(int x = 0,int y = 0,int z = -1){
to = x;
w = y;
next = z;
}
}e[maxn<<1];
bool vis[maxn];
int head[maxn],d[maxn],sz[maxn],maxson[maxn],cnt,tot;
int n,k;
void add(int u,int v,int w){
e[tot] = arc(v,w,head[u]);
head[u] = tot++;
}
void dfs(int u,int fa){
sz[u] = 1;
maxson[u] = 0;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
dfs(e[i].to,u);
sz[u] += sz[e[i].to];
maxson[u] = max(maxson[u],sz[e[i].to]);
}
}
int FindRoot(int sum,int u,int fa){
int ret = u;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
int x = max(sum - sz[ret],maxson[ret]);
int y = FindRoot(sum,e[i].to,u);
int z = max(sum - sz[y],maxson[y]);
if(z < x) ret = y;
}
return ret;
}
void dis(int u,int fa,int depth){
d[cnt++] = depth;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to] || depth + e[i].w > k) continue;
dis(e[i].to,u,depth + e[i].w);
}
}
int calc(int u,int fa,int depth){
int ret = cnt = 0;
dis(u,fa,depth);
sort(d, d + cnt);
int low = 0,high = cnt - 1;
while(low < high){
if(d[low]  + d[high] <= k) ret += high - low++;
else --high;
}
return ret;
}
int solve(int u,int fa){
dfs(u,0);
int root = FindRoot(sz[u],u,0);
vis[root] = true;
int ret = calc(root,0,0);
for(int i = head[root]; ~i; i = e[i].next){
if(vis[e[i].to]) continue;
ret -= calc(e[i].to,root,e[i].w);
ret += solve(e[i].to,root);
}
return ret;
}
int main(){
int u,v,w;
while(scanf("%d%d",&n,&k),n||k){
memset(head,-1,sizeof head);
memset(vis,false,sizeof vis);
tot = 0;
for(int i = 1; i < n; ++i){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
printf("%d\n",solve(1,0));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: