zoukankan      html  css  js  c++  java
  • 数据结构(树,点分治):POJ 1741 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
      点分治模板……
     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 const int maxn=10010;
     7 int cnt,n,k,N;
     8 bool vis[maxn];
     9 int fir[maxn],to[maxn<<1],nxt[maxn<<1],val[maxn<<1];
    10 void addedge(int a,int b,int v){
    11     nxt[++cnt]=fir[a];fir[a]=cnt;val[cnt]=v;to[cnt]=b;
    12 }
    13 
    14 int rt,sz[maxn],son[maxn];
    15 int st[maxn],tot,dis[maxn];
    16 void Get_RT(int x,int fa){
    17     sz[x]=1;son[x]=0;
    18     for(int i=fir[x];i;i=nxt[i])
    19         if(to[i]!=fa&&!vis[to[i]]){
    20             Get_RT(to[i],x);
    21             sz[x]+=sz[to[i]];
    22             son[x]=max(sz[to[i]],son[x]);
    23         }
    24     son[x]=max(son[x],N-sz[x]);    
    25     if(!rt||son[rt]>son[x])rt=x;    
    26 }
    27 
    28 void DFS(int x,int fa){
    29     st[++tot]=dis[x];
    30     for(int i=fir[x];i;i=nxt[i])
    31         if(to[i]!=fa&&!vis[to[i]]){
    32             dis[to[i]]=dis[x]+val[i];
    33             DFS(to[i],x);
    34         }
    35 }
    36 
    37 int Calc(int x,int d){
    38     int ret=0;tot=0;
    39     dis[x]=d;DFS(x,0);
    40     sort(st+1,st+tot+1);
    41     int l=1,r=tot;
    42     while(l<r){
    43         if(st[l]+st[r]>k)r-=1;
    44         else {ret+=r-l;l+=1;}
    45     }
    46     return ret;
    47 }
    48 
    49 int Solve(int x){
    50     vis[x]=true;
    51     int ret=Calc(x,0);
    52     for(int i=fir[x];i;i=nxt[i])
    53         if(!vis[to[i]]){
    54             ret-=Calc(to[i],val[i]);
    55             N=sz[to[i]];rt=0;
    56             Get_RT(to[i],0);
    57             ret+=Solve(rt);
    58         }
    59     return ret;    
    60 }
    61 
    62 int main(){
    63     while(true){
    64         scanf("%d%d",&n,&k);
    65         if(!n&&!k)break;cnt=0;N=n;
    66         memset(vis,0,sizeof(vis));
    67         memset(fir,0,sizeof(fir));
    68         for(int i=1,a,b,v;i<n;i++){
    69             scanf("%d%d%d",&a,&b,&v);
    70             addedge(a,b,v);addedge(b,a,v);
    71         }
    72         Get_RT(1,0);
    73         printf("%d
    ",Solve(rt));
    74     }
    75     return 0;
    76 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    css代码中position的定位,baidu+总结
    ibatis_HelloWorld
    v7系统,任务栏的开始图标和其他图标重合问题
    递归方法:输入一个多位整数,计算出从0到该数1出现的个数。
    解决JS:window.close()在Firefox下的不能关闭的问题
    Programming in the MidFuture(转)
    修改blog问题
    面向数据库的高级语言
    F#试用感受
    基于.net的数学编程语言
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5595231.html
Copyright © 2011-2022 走看看