树形DP--求树上任意两点间距离和】的更多相关文章

我是傻逼我是傻逼 #include<bits/stdc++.h> using namespace std; const int maxn=4e5+50; typedef long long ll; const ll mod=998244353; int Laxt[maxn],Next[maxn],To[maxn],cnt; void add(int u,int v){ Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Next[++cnt]=Laxt[v…
在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这里只介绍树形dp 树形dp求树的直径 我们不妨设1号点为根节点,那么这就可以看做一棵有根树. 设D[x]表示从节点x出发,往以x为根的子树走,能够到达的最远距离.设x的子节点分别为y1,y2,y3,...,yt,edge(x,y)表示从x到y的边权,则可以得到状态转移方程: D[x]=max{D[y…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem Description 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个…
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度.请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少? 其中,可以兴建的路线均是双向的,他们之间的长度均大于0. Input 测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述: 接下去m行,每行3…
题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其他所有点距离之和.求所有序列贡献值之和. 思路:假如第一个点是k,那么后面n-1个点共有(n - 1)!种排列,也就是说,第一个点是k那么这样的序列的贡献值为(n - 1)!*(k到其他点距离之和),显然最后答案应该是所有点之间的距离和的两倍 *(n - 1)!.问题转化为了求一棵树上所有点之间的距…
例题:HDU2376   HDU6446(2018CCPC网络赛) 思路:求任意两点间距离和可以转换为->路径长度乘经过路径次数的和. 求经过次数:设这条边两端的点,被经过的次数分别为A和B,那么这条边被经过的次数就是A*B,它对总距离和的贡献就是(A*B*此边长度). 每条边两端点经过次数的计算,可以用一次dfs解决. 任取一点为根,在dfs的过程中,对每个点k记录其子树包含的点数(包括其自身),设点数为sum[k],则k的父亲一侧的点数即为N-sum[k].这个统计可以和遍历同时进行.故时间…
/** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思路:树形dp,定义dp[i][j]表示以i为根,i节点染色为j时候的子树的染色方法数. */ #include<bits/stdc++.h> #define LL long long using namespace std; typedef long long ll; ; ll dp[maxn][…
JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Contest. The contest was always held in the college of software in the past. However, they changed their minds and decided to find the most convenient l…
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心的属性值. 考虑用树形DP. dp[u]表示割去u点,得到的连通分支的节点数的最大值. tot[u]记录以u为根的这棵子树的节点数总和(包括根). 则用一次dfs即可预处理出这两个数组.再枚举每个点,每个点的属性值其实为max(dp[u],n-tot[u]),因为有可能最大的连通分支在u的父亲及以上…
1 #include <bits/stdc++.h> using namespace std; ; vector < vector <int> > g(N); int d1[N],d2[N],d[N]; bool visit[N]; struct node { int id; int w; }; queue <node> q; int n,m; void dfs (int rt) { memset (visit,,sizeof(visit)); while…
A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functionin…
题目链接:点击打开链接 题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的边数应尽量大. 思路:无向无环图的另一个说法是"森林",即由多棵树组成,我们可以先算一棵树上的答案,然后累加起来就行了.本题的优化目标有两个:放置的灯数应尽量少,被两盏灯照亮的边数b应尽量大.为了统一起见,我们把后者替换为:恰好被一盏灯照亮的边数c应尽量少,然后用x=M*a+c作为最小化的目标,其中M是一…
通过回溯法可以求出直径的两个端点,同时注意有负权边的树求直径不可以用两次dfs来求,而必须用dp做 /* 分情况讨论问题 一条边也不加的情况,显然每条边要扫描两次, 该情况的答案是2(n-1) 只加一条边的情况,找到直径,将其变成一个环,在这个环上的所有边只要扫描一次,剩下的边就要扫描两次 设直径为L,该情况下的答案是 2(n-1-L)+L+1=2n-L-1=2(n-1)-(L-1) 加两条边的情况,在加入第一条边出现环的情况下,再加入一条边形成的环会和原来的环有重合 重合的部分任然要扫描两次,…
Cell Phone Network Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires him to set up cell phone towers on his N (1 ≤ N ≤ 10,000) pastures (conveniently numbered 1..N) s…
Balancing Act http://poj.org/problem?id=1655 #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define mt(a,b) memset(a,b,sizeof(a)) using namespace std; ; vector<int> g[M]; int dp[M],num[M],n; void dfs(…
#include <bits/stdc++.h> using namespace std; ; struct T { int to; int w; }; vector < vector <T> > g (N); ];// d[i][0] 正向最大距离 d[i][1] 正向次大距离 d[i][2] 反向最大距离 int p[N]; // 正向最大距离所经过的子节点 int n; void dfs1(int root) {//求正向距离 p[root]=d[root][]=…
hdu2196 Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2903    Accepted Submission(s): 1472 Problem Description A school bought the first computer some time ago(so this computer's id…
hdu4612 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 3184    Accepted Submission(s): 720 Problem Description N planets are connected by M bidirectional channels that allow instant t…
一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对这三种状态定义如下: 1):dp[i][0],表示点 i 属于支配集合,并且以点 i 为根的子树都被覆盖了的情况下支配集中所包含最少点的个数. 2):dp[i][1],表示点 i 不属于支配集合,且以 i 为根的子树都被覆盖,且 i 被其中不少于一个子节点覆盖的情况下支配集所包含最少点的个数. 3)…
原理可以参考大神 LCA_Tarjan (离线) TarjanTarjan 算法求 LCA 的时间复杂度为 O(n+q) ,是一种离线算法,要用到并查集.(注:这里的复杂度其实应该不是 O(n+q) ,还需要考虑并查集操作的复杂度 ,但是由于在多数情况下,路径压缩并查集的单次操作复杂度可以看做 O(1),所以写成了 O(n+q).) #include<bits/stdc++.h> using namespace std; ; ]; struct Query{ int v, id; Query(…
题意: 求一棵树中以某个点为重心最小的子树集, 就是去掉这个点, 图中节点最多的联通块节点最少. 分析: 想知道这个点是不是最优的点, 只要比较它子树的数量和除去这部分其他的数量(它的父节点那部分树), 最后循环一遍找最优即可. #include<stdio.h> #include<vector> #include<algorithm> #include<string.h> #include<iostream> using namespace s…
Tree Cutting After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible cost, he sued Bessie to mitigate his losses. Bessie, feeling vindictive, decided to sabotage Fa…
hdu4607 Park Visit Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2274 Accepted Submission(s): 1005 Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko's Park! Th…
选课 今天又看了一下这道题,竟然AC不了了 自己的学习效率有点低下 要明白本质,搞透彻 #include<bits/stdc++.h> #define REP(i, a, b) for(register int i = (a); i < (b); i++) #define _for(i, a, b) for(register int i = (a); i <= (b); i++) using namespace std; + ; struct Edge{ int to, next;…
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c之间的距离就是树的直径. 用dfs也可以. 模板: ; int head[N]; int dis[N]; bool vis[N]; ,b,mxn=; struct edge { int to,w,next; }edge[N]; void add_edge(int u,int v,int w) { e…
题目链接:https://vjudge.net/problem/POJ-3162 题意:给一棵树,求每个结点的树上最远距离,记为a[i],然后求最大区间[l,r]满足区间内的max(a[i])-min(a[i])<=M. 思路:第一步向hdoj2196那题一样树形dp求出每个结点的最长距离,我的另一篇博客中有写到https://www.cnblogs.com/FrankChen831X/p/11375572.html.求出最远距离a[i]后,建立线段树维护区间的最大最小值.然后用两个指针i,j遍…
本次 5 道题均来自Codeforce 关于树形DP的算法讲解:Here 791D. Bear and Tree Jumps 如果小熊每次能跳跃的距离为1,那么问题变为求树上任意两点之间距离之和. 对于每一条边sum1和sum2分别表示边的左右点数,ans=各边的sum1*sum2之和即为答案. 而本题最大跳跃距离为k,答案变为(ans+sum)/k.sum为每一条边需要多走x步才能整除k的x之和. 树上任意两点间距离len=depth[x1]+depth[y1]-2*depth[f],f表示点…
题目描述 Alice和Bob正在一棵树上玩游戏.这棵树有\(n\)个结点,编号由\(1\)到\(n\).他们一共玩\(q\)盘游戏. 在第\(i\)局游戏中,Alice从结点\(a_i\)出发,Bob从结点\(b_i\)出发.开始时,除了\(a_i\)和\(b_i\)这两个结点外,所有结点都没有染色.结点\(a_i\)被Alice染色,结点\(b_i\)被Bob染色. 接下来,两位玩家轮流移动,两位玩家移动步数之和为\(k_i\)步.Alice走第一步,Bob走第二步,Alice走第三步\(\c…
[BZOJ3743][Coci2015]Kamp Description 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的点)要集中到一个点举行聚会. 聚会结束后需要一辆车从举行聚会的这点出发,把这K个人分别送回去. 请你回答,对于i=1~n,如果在第i个点举行聚会,司机最少需要多少时间把K个人都送回家. Input 第一行两个数,n,K. 接下来n-1行,每行三个数,x,y,z表示x到y之间有一条需要花费z时间的边. 接下来K行,每行一…
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶段的话一般是$f[i][j][0/1]$.$i$表示以$i$为根的子树,$j$一般表示保留$j$个子节点,$0/1$表示选/不选这个节点.一般第三维可以省去. 基本的DP方程 选择节点类 $f[i][0]=f[j][1]$ $f[i][1]=max/min(f[j][0],f[j][1])$ 背包类…