【堆】【DP】Niyaz and Small Degrees(luogu 7600[APIO 2021 T3]/luogu-CF1119F)

正题

luogu 7600[APIO 2021 T3]
luogu-CF1119F


题目大意

给你一棵树,给出每条边割掉的代价,问你对于0⩽k<n0\leqslant k<n0k<n,使得每个点的度数小于k的最小代价


解题思路

首先考虑单询问的情况

可以设fx,1/0f_{x,1/0}fx,1/0表示第x个点到父节点的边连/不连的最小代价

对于点x,最多连k个点,那么要割掉至少degx−kdeg_x-kdegxk个点

假设所有子节点都连,计算出割掉某个子节点的连边的代价(从连到不连,−fson,1+fson,0+len-f_{son,1}+f_{son,0}+lenfson,1+fson,0+len),然后从中选择degx−kdeg_x-kdegxk个最小代价的点(如果割掉更优则尽量割),该操作可以用堆实现

当k较大时,不难发现,很多点已经满足deg⩽kdeg\leqslant kdegk的条件,没有计算的意义

所以对于点x(degx⩽kdeg_x\leqslant kdegxk),x已经满足条件,所以不用管该点,然后在连接的点中加上该点(对于这些点还有意义)

对于每个点,可以用两个堆维护一个可删堆,对于deg>kdeg>kdeg>k的点,用完后要删掉(下一轮中数值会改变),而对于deg⩽kdeg\leqslant kdegk的点,,为数值不会改变,所以不删

综上,每轮将无用的点删掉,然后计算有用的点


代码

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 500010
using namespace std;
ll n, w, h, ans, summ;
ll p[N], s[N], f[N][2], gt[N], addl[N], dell[N], deg[N];
struct lne
{ll x, y, z;
}l[N];
struct rec
{ll to, l;
};
vector<rec>a[N];
bool cmp(lne x, lne y)
{return deg[x.y] > deg[y.y];
}
bool cmpp(ll x, ll y)
{return deg[x] < deg[y];
}
struct heap//可删堆
{priority_queue<int>d1, d2;ll sum;ll sz(){return d1.size() - d2.size();}void clear(){while(d1.size() && d2.size() && d1.top() == d2.top())d1.pop(), d2.pop();return;}void add(ll x){d1.push(x);sum += x;return; }void del(ll x){d2.push(x);sum -= x;clear();return;}void pop(){sum -= d1.top();d1.pop();clear();return;}ll top(){ll g = d1.top();pop();return g;}
}d[N];
void dfs(ll x, ll fa, ll k)
{p[x] = k;f[x][0] = f[x][1] = 0;for (int i = 0; i < a[x].size(); ++i){ll y = a[x][i].to;if (deg[y] <= k) break;if (y != fa)dfs(y, x, k);}ll an = 0, dn = 0, num = deg[x] - k;while(d[x].sz() > num) d[x].pop();for (int i = 0; i < a[x].size(); ++i){ll y = a[x][i].to, z = a[x][i].l;if (deg[y] <= k) break;if (y != fa){if (f[y][1] < f[y][0] + z)//计算代价{f[x][1] += f[y][1];d[x].add(-f[y][1] + f[y][0] + z);dell[++dn] = -f[y][1] + f[y][0] + z;}else num--, f[x][1] += f[y][0] + z;//代价小于1的就直接删,而且要删的边少一条}}f[x][0] = f[x][1];while(d[x].sz() > max(num, 0ll))//已经删的边可能大于要删的边,所以要取maxaddl[++an] = d[x].top();f[x][1] += d[x].sum;while(d[x].sz() > max(num - 1, 0ll))addl[++an] = d[x].top();f[x][0] += d[x].sum;for (int i = 1; i <= an; ++i)d[x].add(addl[i]);//补回去for (int i = 1; i <= dn; ++i)d[x].del(dell[i]);return;
}
int main()
{scanf("%lld", &n);for (ll i = 1; i < n; ++i){w++;scanf("%lld%lld%lld", &l[w].x, &l[w].y, &l[w].z);w++;l[w] = l[w - 1];swap(l[w].x, l[w].y);deg[l[w].x]++;deg[l[w].y]++;summ += l[w].z;}for (ll i = 1; i <= n; ++i)s[i] = i;sort(l + 1, l + 1 + w, cmp);//边从小到大排,当枚举一个点的连边时,如果度数小于等于k,那么接下来的点都没有意义sort(s + 1, s + 1 + n, cmpp);for (ll i = 1; i <= w; ++i)a[l[i].x].push_back((rec){l[i].y, l[i].z});printf("%lld", summ);h = 1;for (ll k = 1; k < n; ++k){ans = 0;while(deg[s[h]] <= k && h <= n)//没用的点删掉{for (ll i = 0; i < a[s[h]].size(); ++i)if (deg[a[s[h]][i].to] > k)d[a[s[h]][i].to].add(a[s[h]][i].l);else break;h++;}for (ll i = h; i <= n; ++i)if (p[s[i]] < k){dfs(s[i], 0, k);ans += f[s[i]][1];}printf(" %lld", ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Boundary(2020多校第二场B)

Boundary&#xff08;2020多校第二场B&#xff09; 文章目录题意&#xff1a;题解&#xff1a;思路1&#xff1a;代码&#xff1a;思路二代码题意&#xff1a; 坐标平面有n个点&#xff08;不与原点&#xff08;0,0&#xff09;重复&#xff09;,现考虑一个圆&#xff0c;&…

.NET Core开发日志——Linux版本的SQL Server

SQL Server 2017版本已经可以在Linux系统上安装&#xff0c;但我在尝试.NET Core跨平台开发的时候使用的是Mac系统&#xff0c;所以这里记录了在Mac上安装SQL Server的过程。最新的SQL Server没有专门为Mac系统准备安装包&#xff0c;但由于Mac系统上支持Docker&#xff0c;所以…

P3313-[SDOI2014]旅行【树链剖分,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P3313 题目大意 nnn个点的一棵树&#xff0c;每个点有一个颜色和权值&#xff0c;有操作 修改一个点的权值修改一个点的颜色询问一条路径的某颜色的权值和询问一条路径的某颜色的权值最大值 解题思路 询问路径直接树剖先&am…

AIsing Programming Contest 2020 总结

A - Number of Multiples 按照题目意思走就行 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; int l,r,d; int main() {IO;cin>>l>>r>>d;if(r<l) swap(l,r);…

【倍增】【线段树】雨林跳跃(luogu 7599[APIO 2021 T2])

正题 luogu 7599[APIO 2021 T2] 题目大意 给你一排树中每棵树的高度&#xff0c;每次跳跃可以跳到左/右边第一棵比该树高的树&#xff0c;问你从A-B中某棵树跳到C-D中的某棵树的最小步数&#xff08;A⩽B<C⩽DA\leqslant B< C\leqslant DA⩽B<C⩽D&#xff09; 解题…

Duration(2020多校第二场D)

Duration&#xff08;2020多校第二场D&#xff09; 文章目录题意题解代码首先&#xff0c;非常感谢出题人出这个题&#xff0c;避免了我全wa的尴尬题意 求两个时间相差多少秒&#xff0c;两个时间为同一天 题解 全部转化成秒&#xff0c;然后求差 代码 #include<bits/s…

dotnetClub 的前世今生

三年之前&#xff0c;我做过一个在线调查&#xff0c;当时有不少人还是对一个在线社区表示出期待。.NET Core 技术正风声水起&#xff0c;所以我就开始了用它来开发一个论坛的计划。最近正式将项目推动到了一个 MVP 的状态。感兴趣的朋友&#xff0c;现在可以访问 preview.dotn…

P3308-[SDOI2014]LIS【最小割】

正题 题目链接:https://www.luogu.com.cn/problem/P3308 题目大意 三个nnn个数字的序列A,B,CA,B,CA,B,C。要求删除其中某些位置iii使得AAA的最长上升子序列至少减少111且删去位置BBB的权值和最小的情况下满足删去位置的CCC值升序排序后字典序最小。 解题思路 首先BBB值最小很…

Codeforces Round #656 (Div. 3)

A.Three Pairwise Maximums 首先最大的在原序列中肯定出现至少两次否则不能构造&#xff0c;即min max max&#xff0c;对于答案min min max肯定满足题意 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm>…

【LCT】网络(luogu 2173/ZJOI2011)

正题 luogu 2173 题目大意 给你一个图&#xff0c;每条边有有一种颜色&#xff08;numcolor⩽10num_{color}\leqslant 10numcolor​⩽10&#xff09;&#xff0c;保证以下性质&#xff1a; 1.一个点连出的同色边数不大于2 2.不存在同色边组成的环 现在让你进行3钟操作&…

【每日一题】7月13日题目精讲—Kingdom

【每日一题】7月13日题目精讲—Kingdom 文章目录题目描述题解&#xff1a;代码:时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 X王国有n位官员&#xff0c;编号从1到n。国…

P3309-[SDOI2014]向量集【线段树,凸壳】

正题 题目链接:https://www.luogu.com.cn/problem/P3309 题目大意 nnn个操作 在序列末尾加入一个向量(x,y)(x,y)(x,y)询问加入的第l∼rl\sim rl∼r个向量中的一个向量和(x,y)(x,y)(x,y)的点积最大值 强制在线&#xff0c;点积的定义为x1x2y1y2x_1x_2y_1y_2x1​x2​y1​y2​ …

CanalSharp-mysql数据库binlog的增量订阅消费组件Canal的.NET客户端

一.前言CanalSharp是阿里巴巴开源项目mysql数据库binlog的增量订阅&消费组件 Canal 的.NET客户端&#xff0c;关于什么是 Canal&#xff1f;又能做什么&#xff1f;我会在后文为大家一一介绍。CanalSharp 这个项目&#xff0c;是由我和 WithLin(主要贡献) 完成&#xff0c;…

Codeforces Round #657 (Div. 2)

A. Acacius and String 爆零&#xff01;太菜了&#xff0c;下来终于把A题代码调AC了 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> #include<cstring> #include<string> using namespace…

【树链剖分】软件管理(luogu 2146/金牌导航 树链剖分-2)

正题 luogu 2146 金牌导航 树链剖分-2 题目大意 有若干软件&#xff0c;除了软件0&#xff0c;所有软件都依赖且只依赖于另外一个软件 当要删除一个软件时&#xff0c;所有依赖于该软件的软件都要删掉 当安装一个软件时&#xff0c;该软件依赖的软件都要安装 问你每次操作…

【每日一题】7月14日题目精讲—压缩

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 给一个由小写字母组成的字符串&#xff0c;我们可以用一种简单的方法来压缩其中的重复…

P3306-[SDOI2013]随机数生成器【BSGS】

正题 题目链接:https://www.luogu.com.cn/problem/P3306 题目大意 给出一个p,a,b,x1,tp,a,b,x_1,tp,a,b,x1​,t&#xff0c;有xiaxi−1bx_iax_{i-1}bxi​axi−1​b 求一个最小的nnn使得xntx_ntxn​t 解题思路 下标缩一下先变成x0x_0x0​会更好算一点&#xff0c;只考虑x0x_0…

【DevOps+LIVE】直播复盘 – DevOps能力成长模型2018首发

昨天晚上小编和DevOpsDays中国核心组织者刘征老师和张乐老师一起嗨了一把&#xff0c;本来规划进行1小时的直播结果延长到了2个小时才结束&#xff0c;观众人数在前半段一直处于增长状态&#xff0c;直到开播一小时到达顶峰。小伙伴也非常给力&#xff0c;一共提出了40多个问题…

Codeforces Round #658 (Div. 2)

A - Common Subsequence 最短相同子序列长度肯定为1&#xff0c;如果一个元素都不相等之间不存在相同子序列 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #define debug(x) cout<<#x<<": "<<x<<" " #include…

【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)

正题 luogu 2486 金牌导航 树链剖分-3 题目大意 给你一棵树&#xff0c;让你进行以下操作&#xff1a; 1.把一条路径染上一个颜色 2.查询一条路径上有多少个颜色段 解题思路 用树链剖分把问题转化为链上问题 然后维护一下左右端点颜色和颜色总数就好了 代码 #include<c…