首页 > 其他分享 >边分治

边分治

时间:2023-12-26 22:12:20浏览次数:22  
标签:sz int siz 分治 tot lst cun

namespace BFZ{
	int k=1,ssz,rt,tot;
	int h[N],dep[N],sz[N],vis[N];
	vector<pair<int,int> > G[N];
	struct AB{
		int a,b,c,n;
	}d[N*2];
	void cun(int x,int y,int z){
		d[++k]={x,y,z,h[x]},h[x]=k;
	}
	void rebuild(int x,int fa){
		int tmp=0,lst=0;
		for(auto p:G[x]){
			int y=p.first,z=p.second;
			if(y==fa) continue;
			tmp++;
			if(tmp==1) cun(x,y,z),cun(y,x,z),lst=x;
			else if(tmp==(int)G[x].size()-(x!=1)) cun(lst,y,z),cun(y,lst,z);
			else tot++,cun(lst,tot,0),cun(tot,lst,0),lst=tot,cun(tot,y,z),cun(y,tot,z);
		}
		for(auto p:G[x]){
			if(p.first==fa) continue;
			rebuild(p.first,x);
		}
	}
	void dfs(int x,int fa){
		for(int i=h[x];i;i=d[i].n){
			int y=d[i].b,z=d[i].c;
			if(y==fa) continue;
			dep[y]=dep[x]+z,dfs(y,x);
		}
	}
	void init(){
		tot=n;
		for(int i=1,x,y,z;i<n;i++){
			scanf("%lld%lld%lld",&x,&y,&z);
			G[x].push_back({y,z}),G[y].push_back({x,z});
		}
		rebuild(1,0);
		dfs(1,0);
	}
	void gt_rt(int x,int fa,int siz){
		sz[x]=1;
		for(int i=h[x];i;i=d[i].n){
			int y=d[i].b;
			if(y==fa||vis[i>>1]) continue;
			gt_rt(y,x,siz),sz[x]+=sz[y];
			int mx_sz=max(siz-sz[y],sz[y]);
			if(mx_sz<ssz) ssz=mx_sz,rt=i;
		}
	}
	void dfs2(int x,int fa,int s,int op){
		if(x<=n) val[x]=s+dep[x],col[x]=op,q[++top]=x;
		for(int i=h[x];i;i=d[i].n){
			int y=d[i].b;
			if(y==fa||vis[i>>1]) continue;
			dfs2(y,x,s+d[i].c,op);
		}
	}
	void solve(int x,int siz){
		ssz=1e9,gt_rt(x,0,siz);
		if(ssz==1e9) return ;
		int i=rt;
		vis[i>>1]=1,top=0;
		dfs2(d[i].a,0,0,0);
		dfs2(d[i].b,0,0,1);
		ans=max(ans,d[i].c+XS::work());
		int sum=sz[d[i].b];
		solve(d[i].a,siz-sum),solve(d[i].b,sum);
	}
}

标签:sz,int,siz,分治,tot,lst,cun
From: https://www.cnblogs.com/hubingshan/p/17929480.html

相关文章

  • 递归与分治
    一、初步递归1、递归特点函数自己调用自己存在直接递归和间接递归一定有退出条件2、递归三要素退出条件递归函数的定义最后的解3、递归优化记录重复的值(存在重复的值才记录)......
  • 【分治查找数组的最大次大元素】
    分治算法介绍分治算法是一种将问题分解成更小子问题,解决子问题,然后将它们的结果合并以解决原始问题的方法。对于查找数组的最大和次大元素,我们可以将数组分成两部分,然后分别查找每个子数组的最大和次大元素,最后将这些结果合并以得到原始数组的最大和次大元素。算法步骤如果数......
  • CDQ分治
    CDQ分治一般珂以替代一些较复杂的高级数据结构,能用来处理偏序问题、优化dp转移等。大概思路就是分治处理点对的关系,分成三类点:\(\mathbf{\small{1}}\lei<j\lemid\)、\(\mathbf{\small{1}}\lei\lemid<j\len\)、\(mid<i<j\len\),然后用额外的\(O(logn)\)的时间去计算第二类......
  • 归并分治
    归并排序是计算机之父"冯·诺依曼"发明的,但这其中隐藏了一种归并分治的思想。这种思想在一些题目中会帮助我们解决很多问题。原理对于一个大问题的答案,如果等于左边子问题的答案+右边子问题的答案+跨越左右问题的答案。在计算跨越左右问题的答案时,左右两边是有序的是否会......
  • 【合并排序链表】分治/优先队列
    合并两个排序链表模拟维护一个合并链表,每次添加两个排序链表中较小val的节点即可模拟代码publicListNodemergeTwo(ListNodea,ListNodeb){if(a==null)returnb;if(b==null)returna;ListNodeans=newListNode(0);Lis......
  • 241. 为运算表达式设计优先级(分治 +记忆化)
    Problem:241.为运算表达式设计优先级给你一个由数字和运算符组成的字符串expression,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以按任意顺序返回答案。生成的测试用例满足其对应输出值符合32位整数范围,不同结果的数量不超过示例1:输入:expression=......
  • [持续更新][数据结构][算法]涵盖线性表、栈、链表、队列、图、动态规划、分治递归、回
    备考考点整理内部排序表格树的主要考点二叉树的常考紧紧抓住\(n_0=n_2+1\)\(n=n_0+n_1+n_2...n_m\)\(n=n_1+2*n_2+3*n_3...m*n_m\)+1哈夫曼树没有度为1的结点,也就是\(n_1=0\)完全二叉树常考总结最大岛屿问题(dfs模板)#include<iostream>#include<algorith......
  • 树分治全家桶
    树分治全家桶树,(是种在路边的绿化植物)是图论当中的一种特殊图,(由于绿化环境作用非常优秀)由于特殊性质丰富,经常出现在我们身边。本文将主要讲述(如何植树)一种树上优美的暴力——树分治。树分治树分治可以将部分\(O(n^2)\)的暴力降至\(O(n\logn)\)级别,尤其适用于树上距离及其......
  • 【刷题记录】20231124 线段树分治
    做题记录:注意到每次相当于\(0\)后面加\(1\),\(1\)后面加\(0\),因此每次可以合并01和10然后将问题规模减半。黑白染色,白格子=lcm+1,黑格子=prime相乘。发现横着竖着有六个质数,斜着只用四个质数。调整一下顺序即可。状压DP。考虑S作为前缀max时S与U-S的排列方案数。S每......
  • 点分治
    点分治是一种在树上进行的分治,可以方便的求解树上路径等问题。例题:P3806【模板】点分治1给定一棵树,询问树上是否存在长度为k的路径。现在我们假设x为根节点,那么一条路径长度为k有两种情况,一种是经过x,一种不经过x,第一种的两个端点在两个不同子树中,第二种的两个端点在同一......