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.
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.
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 }