Tree
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 Source |
[Submit] [Go Back] [Status] [Discuss]
第一道点分治TAT
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e4 + 10; const int inf = 1e8; int siz[maxn],f[maxn],root,tot,k; int head[maxn],e,dist[maxn],d[maxn]; bool vis[maxn]; struct Edge { int to,w,next; }G[maxn<<1]; void AddEdge(int u,int v,int w) { G[++e] = (Edge) {v,w,head[u]};head[u] = e; G[++e] = (Edge) {u,w,head[v]};head[v] = e; } void getroot(int u,int fa) { siz[u] = 1;f[u] = 0; for(int eid = head[u]; eid ; eid = G[eid].next) { int v = G[eid].to; if(v==fa||vis[v])continue; getroot(v,u); siz[u] += siz[v]; f[u] = max(f[u],siz[v]); } f[u] = max(f[u],tot - siz[u]); if(f[u] < f[root]) root = u; } void getdist(int u,int fa) { dist[++dist[0]] = d[u]; for(int eid = head[u]; eid ; eid = G[eid].next) { int v = G[eid].to; if(v==fa||vis[v])continue; d[v] = d[u] + G[eid].w; getdist(v,u); } } int cacu(int u,int now) { dist[0] = 0; d[u] = now; getdist(u,0); sort(dist+1,dist+1+dist[0]); int l = 1,r = dist[0]; int num = 0; while(l < r) { if(dist[l] + dist[r] <= k) { num += r - l; l++; }else r--; } return num; } int solve(int u) { int ans = cacu(u,0);vis[u] = 1; for(int eid = head[u]; eid ; eid = G[eid].next) { int v = G[eid].to; if(vis[v]) continue; ans -= cacu(v,G[eid].w); root = 0; tot = siz[v]; getroot(v,u); ans += solve(root); } return ans; } int main(int argc, char const *argv[]) { int n; while(scanf("%d%d",&n,&k)==2) { if(!n)return 0; for(int i = 1; i <= n; i++)head[i] = 0; for(int i = 1; i <= n; i++)vis[i] = 0; e = 0; for(int i = 1; i < n; i++) { int u,v,w;scanf("%d%d%d",&u,&v,&w); AddEdge(u,v,w); } f[root = 0] = inf; tot = n; getroot(1,-1); int ans = solve(root); printf("%d\n", ans); } return 0; }
原文地址:http://blog.csdn.net/acvcla/article/details/46583705