• 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
    ",ans);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    当年偶然发现的 Java Bug(JDK 9及之前仍未修复)
    Centos 网卡命名规范及信息查看(物理网卡,虚拟网卡)
    Git 合并多个 commit,保持历史简洁
    Java 常用验证方法(commons-validator,hutool)
    Linux 日常操作(质量团队培训材料)
    Linux 帮助命令及工具(tldr,man,help,info)
    springmvc返回html页面解决方案
    二进制和十进制来回转换
    二进制按位与(&) 按位或(|) 异或运算(^)
    Spring容器和springmvc容器的区别联系
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8151250.html
Copyright © 2020-2023  润新知