首页 > 其他分享 >点分治板子

点分治板子

时间:2024-08-01 23:49:47浏览次数:14  
标签:int 分治 cin mxp 板子 edge include root

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
#define int long long 
const int N = 4e4 + 10;
int n, k, root, cnte, cntd, ans;
//cnte:edge的cnt计数器
int mxp[N], vis[N], sz[N], hd[N], dis[N];
//mxp:子树最大节点数量,判断重心,sz:总结点;hd:链式前向星
struct Edge { int to, next,val; }edge[N<<1];
void addedge(int u, int v, int w)
{
	cnte++;
	edge[cnte].to = v;
	edge[cnte].val = w;
	edge[cnte].next = hd[u];
	hd[u] = cnte;
}
void getroot(int u, int father, int n_part)//n_part与总点数n区分,
{
	sz[u] = 1;//sz:数量,子树的节点数量
	mxp[u] = 0;
	for (int i = hd[u]; i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (v == father or vis[v])continue;
		getroot(v, u, n_part);
		sz[u] += sz[v];
		mxp[u] = max(mxp[u], sz[v]);

	}
	mxp[u] = max(mxp[u], n_part - sz[u]);
	if (mxp[u] < mxp[root])root = u;//重心代码
}
void getdis(int u, int d, int father)//逐个判断子树上的节点到目前根节点的距离(根节点是树的重心)
{
	dis[++cntd] = d;
	for (int i = hd[u]; i; i = edge[i].next)
	{
		int v = edge[i].to; int w = edge[i].val;
		if (v == father or vis[v])continue;
		getdis(v, d + w, u);
	}
}
int calc(int u, int d)
{
	cntd = 0;
	getdis(u, d, 0);
	sort(dis + 1, dis + 1 + cntd);
	int sum = 0;
	for (int l = 1, r = cntd;; l++)
	{
		while (r and dis[l] + dis[r] > k)r--;
		if (r < l)break;
		sum += r - l;//总数

	}
	return sum;
}
void solve(int u)//solve给的是根节点
{
	ans += calc(u, 0); //根节点开始
	vis[u] = 1;
	for (int i = hd[u]; i; i = edge[i].next)
	{
		int v = edge[i].to, w = edge[i].val;
		if (vis[v])continue;
		ans -= calc(v, w);//判重
		root = 0;
		mxp[0] = 1e9;
		getroot(v, 0, sz[v]);
		solve(root);
	}
}
signed main()
{
	IOS;
	cin >> n;
	for (int i = 1; i < n; i++)
	{
		int u, v; cin >> u >> v;
		int w; cin >> w;
		addedge(u, v, w); addedge(v, u, w);
	}
	cin >> k;
	root = 0;
	mxp[0] = 1e9;
	getroot(1, 0, n);
	solve(root);
	cout << ans;
	return 0;
}

标签:int,分治,cin,mxp,板子,edge,include,root
From: https://www.cnblogs.com/zzzsacmblog/p/18337825

相关文章

  • 洛谷P2801 教主的魔法之分块板子
    洛谷P2801题解传送锚点摸鱼环节教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是\(N\)个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为\(1,2,\ldots,N\)。每个人的身高一开始都是不超过\(1000\)......
  • 线段树分治小结
    一般来说,这种题目是给定一些信息,比如说边,然后这些信息会在一个时间段内出现。一般来说需要离线,然后建立一棵以维护每个时刻信息的线段树,具体来说就是在每个节点维护一个vector。#121.「离线可过」动态图连通性以经典例题来说,我们根据每条边出现的时刻将它插入到线段树上对应时......
  • 高精板子
    ```cppstructbign{intd[MaxM],len;voidclean(){while(len>1&&!d[len-1])len--;}bign(){fill(d,d+MaxM,0);len=1;}bign(intnum){*this=num;}bign(stringnum){*this=num;}bignoperato......
  • 树分治、动态树分治学习笔记
    点分治点分治适合处理大规模的树上路径信息问题,选取重心,将当前的树拆分为几颗子树,然后递归子树求解问题,但是今天的重点不在这里边分治与点分治类似,选取一条边,均匀地将树分成两个部分,但是对于一个点有多个儿子时,时间复杂度就会非常大,于是我们可以将其转化,这里有两种方法\(1.\)......
  • 归并分治_小和问题
    归并分治原理:1)思考一个问题在大范围上的答案,是否等于,左部分的答案+右部分的答案+跨越左右产生的答案2)计算“跨越左右产生的答案”时,如果加上左、右各自有序这个设定,会不会获得计算的便利性3)如果以上两点都成立,那么该问题很可能被归并分治解决4)求解答案的过程中只需......
  • 算法板子:滑动窗口——应用单调队列,找到窗口中的最小值与最大值
    #include<iostream>usingnamespacestd;constintN=1e6+10;inta[N];//q数组模拟单调队列;q数组存储原数组元素的下标;//递增单调队列的队头始终维护窗口中的最小值;队头存的是窗口中最小值的下标//递减单调队列的队头始终维护窗口中的最大值;队头存的......
  • C141 线段树分治+线性基 P3733 [HAOI2017] 八纵八横
    视频链接:C141线段树分治+线性基P3733[HAOI2017]八纵八横_哔哩哔哩_bilibili   P3733[HAOI2017]八纵八横-洛谷|计算机科学教育新生态(luogu.com.cn)//线段树分治+线性基O(q*logq*logL*logL)#include<iostream>#include<cstring>#include<algorithm>......
  • cdq分治 提高篇
    优化动态规划序列首先要会最长上升子序列的转移,这里就不说了。我们\(i\)位置的初始值为\(a_i\),可能变成的最大值为\(mx_i\),可能变成的最小值为\(mn_i\)。然后如果\(j\)要转移到\(i\),则需要满足:\(j<i,mx_j\lea_i,a_j\lemn_i\)。然后考虑把\([l,mid]\)按照\(mx\)......
  • MSPM0G3507——电赛PCB板子,小零件太多,酌情使用
    只有CSDN一个账号,其他平台没有账号!只有CSDN一个账号,其他平台没有账号!只有CSDN一个账号,其他平台没有账号!原理图PCB文件完全免费分享。绘制了一个基于官方LP-MSPM0G3507开发板的控制题万用拓展底板;全外设集成,板载以下模块:1.板载一个三串18650电池盒与电池保护,充电芯片,可......
  • cdq分治
    简介前置芝士:归并排序。\(cdq\)分治是个离线算法,可以解决三维偏序或者优化\(dp\)。题目直接上个题目:陌上花开。维护三维偏序有个口诀:一维排序,二维归并,三位数据结构。考虑第一维直接排序解决掉,然后还剩两维。我们考虑第二维用归并排序解决掉。然后假设当前区间\([l,r]\),......