P4178 Tree

最简单的点分治

淀粉质的思想:

“分而治之”,缩小问题规模,合并求解;

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<iostream>
  6 using namespace std;
  7 #define up(i,l,r) for(register int i = (l); i <= (r); ++i)
  8 #define dn(i,l,r) for(register int i = (l); i >= (r); --i)
  9 #define ll long long
 10 #define re register
 11 using namespace std;
 12
 13 template <typename T> void in(T &x) {
 14     x = 0; T f = 1; char ch = getchar();
 15     while(!isdigit(ch)) {if(ch == ‘-‘) f = -1; ch = getchar();}
 16     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
 17     x *= f;
 18 }
 19
 20 template <typename T> void out(T x) {
 21     if(x < 0) x = -x , putchar(‘-‘);
 22     if(x > 9) out(x/10);
 23     putchar(x%10 + 48);
 24 }
 25 //---------------------------------------------------------
 26
 27 const int N = 40007;
 28
 29 struct edge {
 30     int v,w,nxt;
 31 } e[N<<1];int tot,head[N];
 32
 33 void add(int u,int v,int w) {
 34     e[++tot].v = v;
 35     e[tot].w = w;
 36     e[tot].nxt = head[u];
 37     head[u] = tot;
 38 }
 39 //---------------------------------------------------------
 40
 41 int n,k,ans;
 42 int size[N];
 43 int Tsize,cnt,rt;
 44 int cdis[N],dis[N];
 45 bool vis[N];
 46
 47 int f[N];
 48 void get_rt(int u,int fa) {
 49     size[u] = 1; f[u] = 0;
 50     for(re int i = head[u]; i; i = e[i].nxt) {
 51         int v = e[i].v; if(v == fa || vis[v]) continue;
 52         get_rt(v,u);
 53         size[u] += size[v];
 54         f[u] = max(size[v],f[u]);
 55     }
 56     f[u] = max(f[u],Tsize-size[u]);
 57     if(f[u] < f[rt]) rt = u;
 58 }
 59
 60 void get_dis(int u,int fa) {
 61     cdis[++cnt] = dis[u];
 62     for(re int i = head[u]; i; i = e[i].nxt) {
 63         int v = e[i].v; if(v == fa || vis[v]) continue;
 64         dis[v] = dis[u] + e[i].w; get_dis(v,u);
 65     }
 66 }
 67
 68 int calc(int u) {
 69     cnt = 0,get_dis(u,0);
 70     sort(cdis+1,cdis+cnt+1);
 71     int l = 1,r = cnt,sum = 0;
 72     while(l < r) {
 73         if(cdis[l] + cdis[r] <= k) sum += r-l,++l;
 74         else --r;
 75     }
 76     return sum;
 77 }
 78
 79 void new_tree(int u) {
 80     vis[u] = 1; dis[u] = 0;//
 81     ans += calc(u);
 82     for(re int i = head[u]; i; i = e[i].nxt) {
 83         int v = e[i].v; if(vis[v]) continue;
 84         dis[v] = e[i].w;//
 85         ans -= calc(v);
 86         rt = 0,Tsize = size[v];
 87         get_rt(v,0); new_tree(rt);
 88     }
 89 }
 90
 91
 92 void init() {
 93     memset(head,0,sizeof(head));
 94     memset(vis,0,sizeof(vis));
 95     Tsize = n,rt = 0,f[0] = n+1; ans = 0;
 96 }
 97
 98 int main() {
 99     freopen("input.txt","r",stdin);
100     in(n);
101     init(); int x,y,w;
102     up(i,1,n-1) in(x),in(y),in(w),add(x,y,w),add(y,x,w);in(k);
103     get_rt(1,0); new_tree(rt);
104     out(ans); putchar(‘\n‘);
105 }

原文地址:https://www.cnblogs.com/mzg1805/p/10737145.html

时间: 2024-07-31 22:28:08

P4178 Tree的相关文章

[Luogu P4178]Tree (点分治+splay)

题面 传送门:https://www.luogu.org/problemnew/show/P4178 Solution 首先,长成这样的题目一定是淀粉质跑不掉了. 考虑到我们不知道K的大小,我们可以开一个splay来统计比某个数小的数的数量. 具体做法等我开淀粉质讲解的坑再满满填(咕) Code #include<iostream> #include<vector> #include<cstdio> using namespace std; long long read

luogu P4178 Tree

传送门 板子ex 开始天真的以为把m组询问改成k组询问就行了 但是板子里面的两层循环求方案实在是接受不了 所以套一个树状数组统计答案就行 注意大于k的边权全都不要 Code: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ms(a,b) memset(a,b,sizeof a) 5 #define rep(i,a,n) for(int i = a;i <= n;i++)

easyui js取消选中 Tree 指定节点

取消所有选中 var rootNodes = treeObject.tree('getRoots'); for ( var i = 0; i < rootNodes.length; i++) { var node = treeObject.tree('find', rootNodes[i].id); treeObject.tree('uncheck', node.target); }

Maximum Depth of Binary Tree

这道题为简单题 题目: Given a binary tree, find its maximum depth.The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 思路: 我是用递归做的,当然也可以用深搜和广搜,递归的话就是比较左右子树的深度然后返回 代码: 1 # Definition for a binary tre

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

SPOJ375 Query on a tree

https://vjudge.net/problem/SPOJ-QTREE 题意: 一棵树,每条边有个权值 两种操作 一个修改每条边权值 一个询问两点之间这一条链的最大边权 点数<=10000 多组测试数据,case<=20 Example Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3 #include<cstdio> #include<iostream> #include&

POJ 1741 Tree(树的点分治,入门题)

Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v)=The min distance between node u and v.Give an in

命令-tree

tree命令 tree - list contents of directories in a tree-like format. 显示目录的层级结构: tree 命令英文理解为树的意思,其功能是创建文件列表,将目录所有文件以树状的形式列出来.linux中的tree命令默认并不会安装,所以需要通过yum install tree -y来安装此命令. [SYNOPSIS] tree [options] [directory] [OPTIONS] -L level:指定要显示的层级: -d:仅列出目

[LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数

Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST. Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than or equal to the nod