zoukankan      html  css  js  c++  java
  • [bzoj 1468][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

    又一道点分治膜版题
    我果然是只会做膜版啊
    还是贴上vector造图的代码吧
    虽然它RE了
    用数组膜你邻接表AC
    我也很迷啊

    好好好一个小时后的我发现自己一个小时前太sb了
    居然忘了复原vector G了
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<vector>
      6 using namespace std;
      7 
      8 inline int read(){
      9     char ch;
     10     int re=0;
     11     bool flag=0;
     12     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
     13     ch=='-'?flag=1:re=ch-'0';
     14     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
     15     return flag?-re:re;
     16 }
     17 
     18 struct edge{
     19     int to,w;
     20     edge(int to=0,int w=0):
     21         to(to),w(w){}
     22 };
     23 const int maxn=10005;
     24 vector<edge> G[maxn];
     25 int son[maxn],F[maxn];
     26 int d[maxn],deep[maxn];
     27 bool vis[maxn];
     28 int sum,ans,root;
     29 int n,K;
     30 
     31 inline void add_edge(int from,int to,int w){
     32     G[from].push_back(edge(to,w));
     33     G[to].push_back(edge(from,w));
     34 }
     35 
     36 bool init(){
     37     n=read();
     38     if(!n)  return 0;
     39     memset(G,0,sizeof G);
     40     memset(vis,0,sizeof vis);
     41     K=read();
     42     for(int i=0;i<n-1;i++){
     43         int from=read(),to=read(),w=read();
     44         add_edge(from,to,w);
     45     }
     46     return 1;
     47 }
     48 
     49 void getroot(int x,int fa){
     50     son[x]=1;
     51     F[x]=0;
     52     int dd=G[x].size();
     53     for(int i=0;i<dd;i++){
     54         edge &e=G[x][i];
     55         if(e.to!=fa&&!vis[e.to]){
     56             getroot(e.to,x);
     57             son[x]+=son[e.to];
     58             F[x]=max(F[x],son[e.to]);
     59         }
     60     }
     61     F[x]=max(F[x],sum-son[x]);
     62     if(F[x]<F[root])  root=x;
     63 }
     64 
     65 void getdeep(int x,int fa){
     66     deep[++deep[0]]=d[x];
     67     int dd=G[x].size();
     68     for(int i=0;i<dd;i++){
     69         edge &e=G[x][i];
     70         if(e.to!=fa&&!vis[e.to]){
     71             d[e.to]=d[x]+e.w;
     72             getdeep(e.to,x);
     73         }
     74     }
     75 }
     76 
     77 int calc(int x,int now){
     78     d[x]=now;
     79     deep[0]=0;
     80     getdeep(x,0);
     81     sort(deep+1,deep+deep[0]+1);
     82     int t=0;
     83     for(int l=1,r=deep[0];l<r;){
     84         if(deep[l]+deep[r]<=K){
     85             t+=r-l;
     86             l++;
     87         }
     88         else  r--;
     89     }
     90     return t;
     91 }
     92 
     93 void work(int x){
     94     ans+=calc(x,0);
     95     vis[x]=1;
     96     int dd=G[x].size();
     97     for(int i=0;i<dd;i++){
     98         edge &e=G[x][i];
     99         if(!vis[e.to]){
    100             ans-=calc(e.to,e.w);
    101             sum=son[e.to];
    102             root=0;
    103             getroot(e.to,root);
    104             work(root);
    105         }
    106     }
    107 }
    108 
    109 void solve(){
    110     sum=F[root=0]=n;
    111     ans=0;
    112     getroot(1,0);
    113     work(root);
    114     printf("%d
    ",ans);
    115 }
    116 
    117 int main(){
    118     //freopen("temp.in","r",stdin);
    119     while(init())
    120         solve();
    121     return 0;
    122 }

    他说你任何为人称道的美丽  不及他第一次遇见你
  • 相关阅读:
    Web开发快速上手
    前端概述
    Python语言进阶
    图像和办公文档处理
    网络编程
    进程和线程
    正则表达式
    面向对象进阶
    面向对象
    js 获取指定时间上月26 ,
  • 原文地址:https://www.cnblogs.com/ZYBGMZL/p/6867523.html
Copyright © 2011-2022 走看看