题目链接 题解 题意 一棵树上有\(m\)条路径,可以将其中一条边的权值改为0,问最长的路径最短是多少 分析 最短的路径最长自然想到二分最长路径,设其为\(dis\) 关键在于如何check check的关键又是将哪条边改为0 贪心,如果所有超过\(dis\)的路径能在一条边上重合,则将那条边改为0,之后再判断改为0后是否最大的路径小于\(dis\):若无法将所有超过\(dis\)的边重合在一条边上,直接return false; 做法 算两个点之间的路径长用dfs + LCA来实现 判断路径之…
树上差分加上二分答案 详细题解待填坑 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; ; ; ; ]; int lcav[MAXM],cf[MAXN],fw[MAXN],lent[MAXN]; int uline[MAXM],vline[MAXM],wline[MAXM]; ,u[MAXN*],v[MAXN*],w[MAXN*],first[MAXN*],nex…
[题意]n个点的树,m条链,求将一条边的权值置为0使得最大链长最小. [算法]二分+树上差分 [题解] 最大值最小化问题,先考虑二分最大链长. 对所有链长>mid的链整体+1(树上差分). 然后扫一遍,对[在所有不满足链上]的边取最大值并check. 具体做法:对于二分的最大链长,将所有链长>mid的链取最大值(链的数量记为num),然后用树上差分整体+1. 树上差分:a+1,b+1,lca(a,b)-2.dfs的时候判断子节点的连边(若子节点权=num则连边参与比较),然后再把子节点权加进来…
下午用一个小时看了一下树上差分,打了个差分模板,A了3题,真的爽! 题目描述: 公元2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去.显然,飞船驶过一条航道是需要时间的,对于航道j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任…
https://daniu.luogu.org/problem/show?pid=2680 使完成所有运输计划的时间最短,也就是使时间最长的运输计划耗时最短.最大值最小问题考虑用二分答案,每次check(mid)检查时间最长的运输计划耗时是否小于等于mid,二分出使得check(mid)==true的最小mid值. check函数怎么写是本题的难点.耗时小于mid的运输计划不会影响check的结果.耗时大于mid的运输计划肯定需要改造他们的共同边才有可能使它们耗时都小于mid,而有多条共同边的时…
题目链接 题解 题意: 有一些格子,每个格子有一定分数. 给你四种卡片,每次可以使用卡片来前进1或2或3或4个格子并拾取格子上的分数 每张卡片有数量限制.求最大分数. 分析 设\(dp[i]\)为第前\(i\)个格子所能得到的最大分数 显然有一个简单的转移方程 \(dp[i] = \max(dp[i-1] ,dp[i-2],dp[i-3],dp[i-4])\) 等等,,卡片有数量限制!所以上面的方程就不行了 换一个思路,既然它有限制,就以毒攻毒设\(dp[i][j][k][l]\)为用了\(i\…
题目链接 题解 题意 给你一个无向图,求两个点之间的一条路径,使路径上的最小值最大 算法:Kruskal最大生成树+倍增lca 分析 首先容易知道,答案一定在该图的最大生成树上 之后问题便转换成了树上点\(u\)到\(v\)的简单路径42中最小的边权 经典的树上倍增 用fa[i][j]来表示从第\(i\)个点往上\(2^j\)条边到达的点 用s[i][j]来表示从第\(i\)个点往上\(2^j\)条边中的最小值 答案就是在求lca的过程中统计一下最小值就可以了(具体详见代码) 复杂度: Krus…
题目链接 题解 算法: 一个经典的并查集 但是需要用一点贪心的思想 做法: 先将给的冲突们按冲突值从大到小进行排序(这很显然) 然后一个一个的遍历它们 如果发现其中的一个冲突里的两个人在同一个集合里,直接输出当时的冲突值 否则,第一个人不妨设其为\(x\),用一个\(op[x]\)来保存上一个与他冲突的人.如果\(op[x]\)为\(0\),也就是还没有上一个冲突,直接将\(op[x]\)赋值为当时的第二个人(不妨设其为\(y\));如果有冲突,则直接将\(op[x]\)与\(y\)合并. 代码…
题目链接 题意:给定一个无根树,每个点有一个权值.若两个点 \(i,j\) 之间距离为\(2\),则有联合权值 \(w_i \times w_j\).求所有的联合权值的和与最大值 分析: 暴力求,每个节点遍历一遍周围的点,对每个点再遍历一次 可以拿到70分 考虑正解.对于一个点\(u\),周围一圈可以到达的点中,从中任选两个不同的点\(i,j\),则这两个点构成联合权值. 所以我们对一个点维护三个值:周围一圈点\(w_i\)之和\(sumw_u\),\(w_i\)的最大值\(first_u\),…
这题思路很简单: 先对每个询问求距离,对距离由大到小排序, 二分最小距离,验证是否可行,验证时用差分处理: #include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> #include<iomanip> #include<map> #include<set> #include<vec…