POJ - 1741 Tree(点分治模板题)
题目链接:点击查看
题目大意:给出一棵 n 个节点的树,现在定义 dis( x , y ) 为点 x 和点 y 之间的路径长度,现在问 dis ( x , y ) <= k 的点对有多少
题目分析:点分治的模板题目,干货博客:https://www.cnblogs.com/PinkRabbit/p/8593080.html
自己写的时候写了一堆bug。。提示一下,如果是WA的话可能有点无从下手,但如果用的是链式前向星,还仍然 TLE 的话,大概率是重心的地方出现细节问题了,因为如果重心使用不当,会将时间复杂度退化为 n*n*logn
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e4+100;int ans,root,Tsize,wt[N],sz[N],path[N],tot,cnt,n,k;int nt[N<<1],to[N<<1],w[N<<1],head[N];bool vis[N];void addedge(int u,int v,int val)
{to[cnt]=v;w[cnt]=val;nt[cnt]=head[u];head[u]=cnt++;
}void get_root(int u,int fa)
{sz[u]=1;wt[u]=0;for(int i=head[u];i!=-1;i=nt[i]){if(to[i]==fa||vis[to[i]])continue;get_root(to[i],u);sz[u]+=sz[to[i]];wt[u]=max(wt[u],sz[to[i]]);}wt[u]=max(wt[u],Tsize-sz[u]);if(wt[root]>wt[u])root=u;
}void get_path(int u,int fa,int deep)
{path[++tot]=deep;for(int i=head[u];i!=-1;i=nt[i]){if(to[i]==fa||vis[to[i]])continue;get_path(to[i],u,deep+w[i]);}
}int calc(int u,int deep)
{tot=0;get_path(u,-1,deep);sort(path+1,path+1+tot);int ans=0,r=tot;for(int l=1;l<=tot;l++){while(r&&path[l]+path[r]>k)r--;if(r<l)break;ans+=r-l;}return ans;
}void solve(int u)
{ans+=calc(u,0);vis[u]=true;for(int i=head[u];i!=-1;i=nt[i]){if(vis[to[i]])continue;ans-=calc(to[i],w[i]);root=0;Tsize=sz[to[i]];get_root(to[i],-1);solve(root);}
}void init(int n)
{Tsize=n;cnt=root=ans=0;wt[root]=inf;memset(head,-1,sizeof(int)*(n+5));memset(vis,false,n+5);
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);while(scanf("%d%d",&n,&k)!=EOF&&n+k){init(n);for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);}get_root(1,-1);solve(root);printf("%d\n",ans);}return 0;
}
POJ - 1741 Tree(点分治模板题)相关推荐
- POJ 1741 Tree 树分治
题意: 给出一颗有\(n (n \leq 10^4)\)个节点的树,和一个\(k\).统计有多少个点对\(u, \, v(u \neq v)\)满足\(u\)到\(v\)的最短距离不超过\(k\). ...
- POJ 1741 Tree(树分治)
去网上搜题解大多数都是说论文,搜了论文看了看,写的确实挺好,直接复制过来. 不过代码中有些细节还是要注意的,参考这篇http://blog.sina.com.cn/s/blog_6d5aa19a010 ...
- POJ 1741 Tree(点分治)
题意 一棵 \(n\) 个节点的树,求两点间距离不超过 \(k\) 的点对对数. 思路 点分治模板题,点分治一般用来解决树上的路径问题,核心在于找出重心,算经过重心的合法路径,然后以重心把树劈成若干个 ...
- [POJ 1741] Tree
Link: POJ 1741 传送门 Solution: 此题的难点在于点分治上的统计 如果依然采取每棵子树的结果与之前所有子树的结果合并的方式会比较麻烦 同时复杂度可能超过$O(n*log(n))$ ...
- poj 1741 Tree
点分治裸题23333这个题如果K很大的话就不能用依次处理每棵子树做了.(数组存不开2333) 这个就只能是总的依次减去每棵子树里的. 1 #include<cstdio> 2 #inclu ...
- POJ 1741 Tree(树的点分治)
题目链接:http://poj.org/problem?id=1741 题意:给出一棵树,定义dis(u,v)为两个节点之间的距离.dis(u,v)<=K时成(u,v)是合法的.问有多少个合法的 ...
- POJ:3461-Oulipo(KMP模板题)
原题传送:http://poj.org/problem?id=3461 Oulipo Time Limit: 1000MS Memory Limit: 65536K Description The F ...
- bzoj 1468 Tree(点分治模板)
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1527 Solved: 818 [Submit][Status][Discus ...
- The 2019 ACM-ICPC Shannxi J. And And And (点分治模板题)
J. And And And A tree is a connected graph without cycles. You are given a rooted tree with nn nodes ...
最新文章
- 不同浏览器Cookie有效期问题
- 14.parfor并行循环处理
- centos7下kafka2.12-2.1.0的安装及使用
- 【Python】青少年蓝桥杯_每日一题_9.03_画三角形和半圆相切
- npm run serve后台运行的命令写法
- Tomcat9URL不支持特殊字符解决方案
- 以太网 数据包速率计算方法
- Android官方开发文档Training系列课程中文版:连接无线设备之通过WIFI创建P2P连接
- python模块使用相对路径还是绝对路径、哪种更好_python学习的第十八天模块之包、相对搜索路径和绝对搜索路径...
- 2020年有赞云生态发展白皮书
- linux下文件删除的原理精华讲解(考试题答案系列)
- 抖音内测语音直播功能 支持8位观众同时在线聊天
- .NET Web实时消息后台服务器推送技术-GoEasy
- 有36匹马,六个跑道。没有记时器等设备,用最少的比赛次数算出跑的最快的前3匹马
- resolving xxx failed: Temporary failure in name resolution解决
- c++ file* 句柄泄漏_C/C++连接MySql数据库使用总结
- Atitit 歌曲年份抓取的nlp ai项目 原理通过百度搜索,抓取第一页数据,正则数字,过滤年份。。 显示格式。。歌曲,年份,年份周围前后40字符,方便核对 通过百科抓取比较准确 红尘情歌
- 报表工具如何实现多次导入Excel
- WinHttp编程步骤
- RS485串口模块详解RS232、RS485、RS485