树套树Day2暂且搁置...因为Day1的题我各种不会做...

唯一过了一道还是整体二分过的...

我们来一点愉快的算法,先不考虑数据结构这种骚东西了

毕竟还在发烧,就先码码这几天在搞的点分治吧

hx你又挖一个大坑赶紧去填树套树

点分治用于解决“树上路径点权统计问题”

...讲不太清楚,大家可以直接看题

点分治的思想呢,就是我们在树上走路径的时候,对于一个点,有两种方案:

1.选

2.不选

如果“不选”一个点,我们可以知道我们也会“不选”他的子树,递归处理即可

如果选一个点,有一个特别重要的性质:

如果一条路径要经过这个点,那么他必然是由两条在这个点不同子树中到这个点的路径组合而成

然后我们面临两条选择

1.直接dfs做

2.“动态点分治”(Orz popoqqq大爷)

由于是Day1...

我们来讲讲dfs!

我们知道,树这个东西是递归定义的,所以我们处理一棵树相当于处理它的根节点,然后递归处理它的每个子树

现在我们面临一个问题:根节点可以是任意的,我们怎么选根节点呢

考虑贪心的思想:让递归层数最小

我们每次选出的根节点要让这棵树的“总深度”最小

大概就是这样的

void getroot(int v,int fa)
{
son[v] = ; f[v] = ;//f记录以v为根的最大子树的大小
for(int i = head[v];i;i=e[i].next)
if(e[i].to != fa && !vis[e[i].to]) {
getroot(e[i].to,v);//递归更新
son[v] += son[e[i].to];
f[v] = max(f[v],son[e[i].to]);//比较每个子树
}
f[v] = max(f[v],sum-son[v]);//别忘了以v父节点为根的子树
if(f[v] < f[root]) root = v;//更新当前根
}

Getroot

理解了这个思想,我们就可以看一下下面的例题:

poj1741

给一颗n个节点的树,每条边上有一个距离v(v<=1000)。定义d(u,v)为u到v的最小距离。给定k值,求有多少点对(u,v)使u到v的距离小于等于k。数据范围:n<=10000,k<2^31

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
using namespace std;
#define INF 0x7fffffff
struct node{int y,v,next;}e[];
int n,len,k,root,sum,ans,Link[],f[],vis[],son[],d[],deep[];
inline int read()
{
int x=,f=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-; ch=getchar();}
while(isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
void insert(int x,int y,int v)
{
e[++len].next=Link[x];
Link[x]=len;
e[len].v=v;
e[len].y=y;
}
void getroot(int x,int fa)
{
son[x]=; f[x]=;
for(int i=Link[x];i;i=e[i].next)
{
if(e[i].y==fa||vis[e[i].y]) continue;
getroot(e[i].y,x);
son[x]+=son[e[i].y];
f[x]=max(f[x],son[e[i].y]);
}
f[x]=max(f[x],sum-son[x]);
if(f[x]<f[root]) root=x;
}
void getdeep(int x,int fa)
{
deep[++deep[]]=d[x];
for(int i=Link[x];i;i=e[i].next)
{
if(e[i].y==fa||vis[e[i].y]) continue;
d[e[i].y]=d[x]+e[i].v;
getdeep(e[i].y,x);
}
}
int cal(int x,int v)
{
d[x]=v; deep[]=;
getdeep(x,);
sort(deep+,deep+deep[]+);
int l=,r=deep[],sum=;
while(l<r)
{
if(deep[l]+deep[r]<=k) {sum+=r-l; l++;}
else r--;
}
return sum;
}
void solve(int x)
{
ans+=cal(x,);//计算答案
vis[x]=;
for(int i=Link[x];i;i=e[i].next)
{
if(vis[e[i].y]) continue;
ans-=cal(e[i].y,e[i].v);//计算不符合题意的答案
sum=son[e[i].y];
root=;
getroot(e[i].y,);
solve(root);
}
}
int main()
{
freopen("cin.in","r",stdin);
freopen("cout.out","w",stdout);
while()
{
ans=,root=,len=;
memset(vis,,sizeof(vis));
memset(Link,,sizeof(Link));
n=read(); k=read();
if(n==&&k==) break;
for(int i=;i<=n-;i++)
{
int x=read(),y=read(),v=read();
insert(x,y,v); insert(y,x,v);
}
f[]=INF; sum=n;
getroot(,);
solve(root);
printf("%d\n",ans);
}
return ;
}

题解:对于每个点记录子树中出现的距离值,对于一棵树的距离值数组,把它排序求一次ans1,再对每棵子树分别求一个自己对自己的ans2,ans1-Σans2即为最后的ans。

例题:

bzoj2599

poj1741

bzoj2152

这回有完整代码了...

明天更树套树Day2

近期要更的:

树套树Day2

数据结构综合刷题Day1

FFT&NTT综合刷题(这个不知道要几天...)

矩阵练习.pdf(我真是日了...)

杜教筛刷题

莫比乌斯反演刷题

点分治Day2

CDQ分治&整体二分

点分治Day1的更多相关文章

  1. loj#6031. 「雅礼集训 2017 Day1」字符串(SAM 广义SAM 数据分治)

    题意 链接 Sol \(10^5\)次询问每次询问\(10^5\)个区间..这种题第一感觉就是根号/数据分治的模型. \(K\)是个定值这个很关键. 考虑\(K\)比较小的情况,可以直接暴力建SAM, ...

  2. 「雅礼集训 2017 Day1」字符串 SAM、根号分治

    LOJ 注意到\(qk \leq 10^5\),我们很不自然地考虑根号分治: 当\(k > \sqrt{10^5}\),此时\(q\)比较小,与\(qm\)相关的算法比较适合.对串\(s\)建S ...

  3. 2019 牛客国庆集训day1 2019 点分治

    题目链接:https://ac.nowcoder.com/acm/contest/1099/I 点分治,计算路径数的时候,先将每个点到根的距离模2019,计算的时候就可以O(n)求出数目,对于模201 ...

  4. [gdoi2018 day1]小学生图论题【分治NTT】

    正题 题目大意 一张随机的\(n\)个点的竞赛图,给出它的\(m\)条相互无交简单路径,求这张竞赛图的期望强联通分量个数. \(1\leq n,m\leq 10^5\) 解题思路 先考虑\(m=0\) ...

  5. 【BZOJ-2229】最小割 最小割树(最大流+分治)

    2229: [Zjoi2011]最小割 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1565  Solved: 560[Submit][Status ...

  6. contesthunter CH Round #64 - MFOI杯水题欢乐赛day1 solve

    http://www.contesthunter.org/contest/CH Round %2364 - MFOI杯水题欢乐赛 day1/Solve Solve CH Round #64 - MFO ...

  7. 8.4 正睿暑期集训营 Day1

    目录 2018.8.4 正睿暑期集训营 Day1 A 数对子 B 逆序对 C 盖房子 考试代码 A B C 2018.8.4 正睿暑期集训营 Day1 时间:4.5h(实际) 期望得分:30+50+3 ...

  8. 2019暑期金华集训 Day1 组合计数

    自闭集训 Day1 组合计数 T1 \(n\le 10\):直接暴力枚举. \(n\le 32\):meet in the middle,如果左边选了\(x\),右边选了\(y\)(且\(x+y\le ...

  9. 2019暑期金华集训 Day1 数据结构

    自闭集训 Day1 数据结构 CF643G 用类似于下面的方法,搬到线段树上. 如何合并两个集合?先全部放在一起,每次删掉最小的\(cnt_i\),然后把其他所有的\(cnt\)都减去\(cnt_i\ ...

随机推荐

  1. Linux下SVN安装与权限管理

    cat /etc/redhat-release //查看系统版本号 CentOS release 7.1 (Final) 这里我们採用yum源安装方式: 1.安装svn yum install sub ...

  2. 自定义 ViewController 容器转场

    本文转载至 http://blog.csdn.net/yongyinmg/article/details/40621463 在话题 #5 中,Chris Eidhof 向我们介绍了 iOS7 引入的新 ...

  3. Spring JDBC查询返回对象代码跟踪

    在封装方法的时候突然发现通过 ResultSetMetaData的getColumnCount()获取到的列明会多一列(ROWSTAT),而且每次的值都是1,目前没有找到相关信息,在国外网站上看到有类 ...

  4. 软件测试人员需要精通的开发语言(3)--- Linux

    Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.不得不说下,中国产的红旗系统,牛的一逼,造价很贵,但具体何用处估 ...

  5. EasyNVR无插件直播服务器软件使用详情功能 - 录像功能说明

    背景介绍 EasyNVR不仅仅拥有无插件的直播功能,更拥有对于直播录像的存储和日期检索功能: 本篇博文主要用于介绍EasyNVR的录像功能. 之前有博文介绍相关的录像功能,本篇主要为了介绍录像的新功能 ...

  6. 阿里巴巴fastjson 包的使用解析json数据

    Fastjson是一个Java语言编写的高性能功能完善的JSON库.由阿里巴巴公司团队开发的. 主要特性主要体现在以下几个方面: 1.高性能 fastjson采用独创的算法,将parse的速度提升到极 ...

  7. CentOS7.1安装 Vsftpd FTP 服务器

    # yum install vsftpd 安装 Vsftpd FTP 编辑配置文件 ‘/etc/vsftpd/vsftpd.conf’ 用于保护 vsftpd. # vi /etc/vsftpd/vs ...

  8. 帝国cms数据表中文说明

    本文介绍下,帝国cms中各数据表的用途,有需要的朋友,参考下吧. 帝国cms各数据表及用途说明. phome_ecms_infoclass_news 新闻采集规则记录表 phome_ecms_info ...

  9. 有关java之反射的使用

    1 public class Demo02 { 2 @SuppressWarnings("all") 3 public static void main(String[] args ...

  10. Kattis - friday 【数学】

    题意 每一年的第一天 都是星期天 然后 给出 一年的总天数 和 总月数 以及 每个月 的总天数 求出 有多少个星期五 是当月的13号 思路 对于 每个月 只要判断 当月的13号 是不是 星期五 就可以 ...