poj1741_Tree(树的点分治入门题)

题目链接:poj1741_Tree

题意:

给你一颗n个节点的树,每条边有一个值,问有多少点对(u,v),满足u->v的最短路径小于k。

题解:

典型的树的分治,板子题。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define F(i,a,b) for(int i=a;i<=b;++i)
 5 using namespace std;
 6 
 7 const int N=1e4+7;
 8 
 9 int n,k,g[N],v[N*2],nxt[N*2],w[N*2],ed,ans;
10 int vis[N],size[N],mx[N],mi,dis[N],tot,root;
11 
12 inline void adg(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}
13 void init(){F(i,1,n)g[i]=0,vis[i]=0;ed=ans=0;}
14 
15 void dfs_size(int u,int fa)
16 {
17     size[u]=1,mx[u]=0;
18     for(int i=g[u];i;i=nxt[i])
19         if(v[i]!=fa&&!vis[v[i]])
20         {
21             dfs_size(v[i],u),size[u]+=size[v[i]];
22             if(size[v[i]]>mx[u])mx[u]=size[v[i]];
23         }
24 }
25 
26 void dfs_root(int r,int u,int fa)
27 {
28     if(size[r]-size[u]>mx[u])mx[u]=size[r]-size[u];
29     if(mx[u]<mi)mi=mx[u],root=u;
30     for(int i=g[u];i;i=nxt[i])
31         if(v[i]!=fa&&!vis[v[i]])
32             dfs_root(r,v[i],u);
33 }
34 
35 void dfs_dis(int u,int d,int fa)
36 {
37     dis[++tot]=d;
38     for(int i=g[u];i;i=nxt[i])
39         if(v[i]!=fa&&!vis[v[i]])
40             dfs_dis(v[i],d+w[i],u);
41 }
42 
43 int calc(int u,int d)
44 {
45     int ans=0;
46     tot=0,dfs_dis(u,d,0);
47     sort(dis+1,dis+1+tot);
48     int i=1,j=tot;
49     while(i<j)
50     {
51         while(dis[i]+dis[j]>k&&i<j)j--;
52         ans+=j-i,i++;
53     }
54     return ans;
55 }
56 
57 void dfs(int u=1)
58 {
59     mi=n,dfs_size(u,0);
60     dfs_root(u,u,0);
61     ans+=calc(root,0),vis[root]=1;
62     for(int i=g[root];i;i=nxt[i])
63         if(!vis[v[i]])ans-=calc(v[i],w[i]),dfs(v[i]);
64 }
65 
66 int main()
67 {
68     while(~scanf("%d%d",&n,&k)&&n+k!=0)
69     {
70         init();
71         F(i,1,n-1)
72         {
73             int x,y,z;
74             scanf("%d%d%d",&x,&y,&z);
75             adg(x,y,z),adg(y,x,z);
76         }
77         dfs();
78         printf("%d\n",ans);
79     }
80     return 0;
81 }
View Code

 

posted @ 2016-11-16 14:45  bin_gege  阅读(167)  评论(0编辑  收藏  举报