点分治总结
来源:互联网 发布:金百福软件 打不开 编辑:程序博客网 时间:2024/06/03 17:01
【介绍】
由于树具有一般的图没有的特点,所以在竞赛中的应用更广。
在一些树上路径问题中,暴力求解时间复杂度过高,往往需要一些更为高效的算法,点分治就是其中之一。
【流程】
首先选取一个点,把无根树变成有根树。
我们可以用树型DP选点。
因为树是递归定义的,所以我们当然希望递归的层数最小。
每次选取的“重心”,(就是相连的结点数最多的连通块的结点数最小的点)
void getrot(int x,int fa){ f_son[x]=1; f[x]=0;//f数组表示当x为根是,以x的子节点为根的最大子树的大小,f_son数组表示以x为根的树的大小 for (int j=lnk[x]; j; j=nxt[j]) if (!vis[son[j]]&&son[j]!=fa) { getrot(son[j],x); f_son[x]+=f_son[son[j]]; f[x]=max(f[x],f_son[son[j]]); } f[x]=max(f[x],nn-f_son[x]);//考虑以x的父节点为根的子树的大小。 if (f[x]<f[rot]) rot=x;//修正当前的根rot。}
【核心代码】
void solve(int x){ vis[x]=1; for (int j=lnk[x]; j; j=nxt[j]) if (!vis[son[j]]) { nn=f_son[son[j]]; rot=0; getrot(son[j],0);//接着遍历子树。 solve(rot); }}int main(){ memset(vis,0,sizeof(vis)); memset(lnk,0,sizeof(lnk)); tot=rot=0; nn=n; f[0]=INF; getrot(1,0);//找根 solve(rot);//点分 printf("%d\n",ans); n=read_(); m=read_();}
阅读全文
1 0
- 点分治总结
- 【点分治总结】
- 点分治总结
- 点分治总结
- 【图论】点分治总结&POJ2114Boatherds题解
- 树分治-点分治
- 点分治
- 点分治
- 点分治
- 点分治
- 点分治
- 点分治。。。。。
- 点分治
- 点分治
- 点分治
- 点分治
- 点分治
- 树的分治-点分治
- less基础
- gcc和g++编译器
- IO流之缓冲流
- WPF简单教程:开篇
- 1017. A除以B (20)
- 点分治总结
- STL--> list 双向循环链表容器 接口使用及介绍。 模拟实现 STL list容器
- AngularJS实现一个HTML元素内容可编辑指令
- [LeetCode]543. Diameter of Binary Tree(计算二叉树的直径的长度)
- C/C++结构体struct的不同
- spring的配置文件applicationContext中没有快捷键问题
- Android studio gradle简单解析及使用指南
- python读取csv文件
- python列表操作,排序