POJ1741

师爷:你叫张麻子?可你脸上没麻子啊!张麻子:黄四郎脸上有四吗?

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 using namespace std;
  6 const int N = 30000;
  7 int key[N], next[N], len[N], head[N], cnt, d[N], s[N], q[N], t, a[N], a_c, f[N], dist, ans, n;
  8 bool no[N];
  9 inline void add (int x, int y, int w)
 10 {
 11     key[cnt] = y;
 12     next[cnt] = head[x];
 13     len[cnt] = w;
 14     head[x] = cnt ++;
 15 }
 16 inline void DFS (int x, int fa)
 17 {
 18     s[x] = 1;
 19     f[x] = 0;
 20     q[++ t] = x;
 21     for (int i = head[x]; ~ i; i = next[i])
 22         if (key[i] != fa && !no[key[i]])
 23         {
 24             DFS (key[i], x);
 25             s[x] += s[key[i]];
 26             f[x] = max (f[x], s[key[i]]);
 27         }
 28 }
 29 inline int findroot (int S)
 30 {
 31     t = 0;int t1 = 0x3f3f3f3f, t2 = 0;
 32     DFS (S, 0);
 33     for (int i = 1; i <= t; i ++)
 34     {
 35         int t = max (f[q[i]], s[S] - s[q[i]]);
 36         if (t < t1)
 37             t1 = t, t2 = q[i];
 38     }
 39     return t2;
 40 }
 41 inline void getdis (int x, int fa)
 42 {
 43     a[++ a_c] = d[x];
 44     for (int i = head[x]; ~ i; i = next[i])
 45         if (key[i] != fa && !no[key[i]])
 46         {
 47             d[key[i]] = d[x] + len[i];
 48             
 49             getdis (key[i], x);
 50         }
 51     
 52 }
 53 inline void getpoint (int x, int fa)
 54 {
 55     a[++ a_c] = d[x];
 56     for (int i = head[x]; ~ i; i = next[i])
 57         if (key[i] != fa && !no[key[i]])
 58             getpoint (key[i], x);
 59 }
 60 inline int slide ()
 61 {
 62     int z (0);
 63     sort (a + 1, a + 1 + a_c);
 64     for (int i = 1, j = a_c; i <= a_c && i < j; i ++)
 65     {
 66         for (; a[i] + a[j] > dist && j > i; j --);
 67         z += j - i;
 68     }
 69     return z;
 70 }
 71 inline void calc (int rt)
 72 {
 73     d[rt] = 0;a_c = 0;
 74     getdis (rt, 0);
 75     ans += slide ();
 76     for (int i = head[rt]; ~ i; i = next[i])
 77         if (!no[key[i]])
 78         {
 79             a_c = 0;
 80             getpoint (key[i], rt);
 81             ans -= slide ();
 82         }
 83 }
 84 inline void F (int S)
 85 {
 86     int rt = findroot (S);
 87     no[rt] = true;
 88     calc (rt);
 89     for (int i = head[rt]; ~ i; i = next[i])
 90         if (!no[key[i]])
 91             F (key[i]);
 92 }
 93 int main ()
 94 {
 95     while (scanf ("%d%d", &n, &dist), n + dist)
 96     {
 97         ans = cnt = 0;
 98         memset (head, -1, sizeof head);
 99         memset (no, 0, sizeof no);
100         for (int i = 1, a, b, c; i <= n - 1; i ++)
101             scanf ("%d%d%d", &a, &b, &c), add (a, b, c), add (b, a, c);
102         F (1);
103         printf ("%d\n", ans);
104     }
105     return 0;
106 }

 

转载于:https://www.cnblogs.com/tellmewtf/archive/2013/01/16/2863544.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值