[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\n",ans);
115 }
116 
117 int main(){
118     //freopen("temp.in","r",stdin);
119     while(init())
120         solve();
121     return 0;
122 }

 


他说你任何为人称道的美丽  不及他第一次遇见你
posted @ 2017-05-17 14:46  ZYBGMZL  阅读(167)  评论(1编辑  收藏  举报