POJ1741 Tree (点分治)

Tree

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 25772   Accepted: 8566

Description

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

code

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 const int N = 10100;
 8 
 9 struct Edge{
10     int to,nxt,w;
11 }e[N<<1];
12 int head[N],son[N],f[N],deth[N],d[N];
13 bool vis[N];
14 int ans,tot,Root,sum,n,k;
15 
16 void init() {
17     memset(head,0,sizeof(head));
18     memset(vis,false,sizeof(vis));
19     ans = tot = Root = 0;
20 }
21 void add_edge(int u,int v,int w) {
22     e[++tot].to = v;e[tot].w = w;e[tot].nxt = head[u];head[u] = tot;
23 }
24 void getroot(int u,int pa) {
25     son[u] = 1;f[u] = 0;
26     for (int i=head[u]; i; i=e[i].nxt) {
27         int v = e[i].to;
28         if (v==pa||vis[v]) continue;
29         getroot(v,u);
30         son[u] += son[v];
31         f[u] = max(f[u],son[v]);
32     }
33     f[u] = max(f[u],sum-son[u]);
34     if (f[u] < f[Root]) Root = u;
35 }
36 void getdeth(int u,int pa) {
37     deth[++deth[0]] = d[u];
38     for (int i=head[u]; i; i=e[i].nxt) {
39         int v = e[i].to,w = e[i].w;
40         if (v==pa||vis[v]) continue;
41         d[v] = d[u] + w;
42         getdeth(v,u);
43     }
44 }
45 int calcc(int u,int w) {
46     deth[0] = 0;
47     d[u] = w;
48     getdeth(u,0);
49     sort(deth+1,deth+deth[0]+1);
50     int l = 1,r = deth[0],ret = 0;
51     while (l < r) {
52         if (deth[l] + deth[r] <= k) ret += r-l,l++;
53         else r--;
54     }
55     return ret;
56 }
57 void work(int u) {
58     ans += calcc(u,0);
59     vis[u] = 1;
60     for (int i=head[u]; i; i=e[i].nxt) {
61         int v = e[i].to,w = e[i].w;
62         if (vis[v]) continue;
63         ans -= calcc(v,w);
64         sum = son[v];
65         Root = 0;
66         getroot(v,0);
67         work(Root);
68     }
69 }
70 int main() {
71     while (scanf("%d%d",&n,&k)!=EOF && !(n==0&&k==0)) {
72         init();
73         for (int a,b,c,i=1; i<n; ++i) {
74             scanf("%d%d%d",&a,&b,&c);
75             add_edge(a,b,c);add_edge(b,a,c);
76         }
77         f[0] = 1e9;
78         sum = n;
79         getroot(1,0);
80         work(Root);
81         printf("%d\n",ans);
82     }
83     return 0;
84 }

 

posted @ 2017-12-30 21:26  MJT12044  阅读(164)  评论(1编辑  收藏  举报