Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 14706 | Accepted: 4781 |
Description
Input
Output
Sample Input
5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0
Sample Output
8
Source
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-6; const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int MOD = 1000000007; #define ll long long #define CL(a,b) memset(a,b,sizeof(a)) #define MAXN 20010 struct node { int v,len;//v是邻接点,len是权值 int sum,bat;//sum是子节点个数,bat是拆当前点后子树的最大结点数 node *next; }tree[MAXN],*head[MAXN],dp[MAXN]; int n,k,ans,pre,root,tot; int vis[MAXN],dist[MAXN]; int size[MAXN],sign[MAXN];//size表示最大分支的结点数,sign是一个hash数组 void init() { ans = pre = 0; for(int i=0; i<MAXN; i++) vis[i]=0, head[i]=NULL; } void add(int a, int b, int c) { tree[pre].v = b; tree[pre].len = c; tree[pre].next = head[a]; head[a] = &tree[pre++]; } void dfs(int son, int father) { dp[son].sum = dp[son].bat = 0; node *p = head[son]; while(p != NULL) { if(p->v!=father&&vis[p->v]==0) { dfs(p->v, son); dp[son].sum += dp[p->v].sum;//累计子节点数 dp[son].bat = max(dp[son].bat, dp[p->v].sum);//找最大分支 } p = p->next; } dp[son].sum++; sign[tot] = son;//hash size[tot++] = dp[son].bat;//记录每个最大分支的结点数 } int GetRoot(int son) { tot = 0; dfs(son, 0); int maxx=INF, maxi, cnt=dp[son].sum; for(int i=0; i<tot; i++) { size[i] = max(size[i], cnt-size[i]); if(size[i] < maxx) { maxx = size[i]; maxi = sign[i]; } } return maxi; } void GetDist(int son, int father, int dis)//保存每个结点到根结点的距离 { node *p = head[son]; dist[tot++] = dis; while(p != NULL) { if(p->v!=father&&vis[p->v]==0&&dis+p->len<=k) GetDist(p->v, son, dis+p->len); p = p->next; } } void count1(int son)//不同支 { sort(dist, dist+tot); int left=0, right=tot-1; while(left < right) { if(dist[left]+dist[right] <= k) ans += (right - left), left++; else right--; } } void count2(int son)//同支 { vis[son] = 1; node *p = head[son]; while(p != NULL) { if(vis[p->v] == 0) { tot = 0; GetDist(p->v, son, p->len); sort(dist, dist+tot); int left=0, right=tot-1; while(left < right) { if(dist[left]+dist[right] <= k) ans -= (right - left), left++; else right--; } } p = p->next; } } int solve(int son, int father) { root = GetRoot(son); tot=0; GetDist(root, 0, 0); count1(root); count2(root); node *p = head[root]; while(p != NULL) { if(p->v!=father&&vis[p->v]==0) solve(p->v, root); p = p->next; } } int main() { int a,b,c; while(scanf("%d%d",&n,&k),n+k) { init(); for(int i=1; i<n; i++) { scanf("%d%d%d",&a,&b,&c); add(a, b, c); add(b, a, c); } solve(1, 0); printf("%d\n",ans); } return 0; }