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 @   bin_gege  阅读(170)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理
点击右上角即可分享
微信分享提示