P7600-[APIO2021]封闭道路【堆,dp】
正题
题目链接:https://www.luogu.com.cn/problem/P7600
题目大意
给出\(n\)个点的一棵树,边有边权,对于每个\(k\)求去掉最小边权和的点使得每个点的度数都不超过\(k\)。
\(1\leq n\leq 10^5\)
题目大意
APIO遇到的原题,和CF1119F一样,感觉要被冲烂。
先考虑暴力的做法,设\(f_{i,0/1}\)表示点\(i\)割不割连接父节点的边时满足子树条件的最小代价,然后对于每个点把每个儿子割掉的代价排个序取最小的一部分就好了,这样时间复杂度\(O(n^2)\)的。
然后优化的话,发现当\(k\)比较大时有很大一部分的点是没有作用的,所以可以考虑删除一些没有用的点。度数小于等于\(k\)的点直接删去,这样的话如果我们就能做到枚举每个没有被删去的点,因为所有点的度数和为\(2n\),这样的复杂度是\(O(n)\)的。
删除的点我们把代价加入父节点处维护的一个堆中,然后每次取出前一部分的点就好了,时间复杂度\(O(n\log n)\)。
还是贴CF那题的代码吧,APIO的那个东西好丑(
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#define ll long long
#define mp(x,y) make_pair(x,y)
using namespace std;
const ll N=3e5+10;
struct Heap{
priority_queue<ll> q1,q2;ll sum;
void Push(ll x){q1.push(x);sum+=x;return;}
void Pop(ll x){q2.push(x);sum-=x;return;}
ll Top(){
while(!q2.empty()&&q1.top()==q2.top())
q1.pop(),q2.pop();
ll w=q1.top();q1.pop();sum-=w;
return w;
}
ll Size(){return q1.size()-q2.size();}
}q[N];
struct node{
ll to,next,w;
}a[N<<1];
ll n,tot,deg[N],f[N][2],ls[N],p[N],v[N];
set<pair<ll,ll> > s[N];queue<ll> cl,del;vector<ll> ans;
void addl(ll x,ll y,ll w){
a[++tot].to=y;deg[y]++;
a[tot].next=ls[x];a[tot].w=w;
ls[x]=tot;return;
}
void dfs(ll x,ll fa,ll k){
f[x][0]=f[x][1]=0;v[x]=k;ll siz=deg[x],S=0;
while(q[x].Size()>siz-k)q[x].Top();
set<pair<ll,ll> >::iterator it;
for(it=s[x].begin();it!=s[x].end();it++){
ll y=(*it).first;
if(y==fa)continue;
dfs(y,x,k);
}
for(it=s[x].begin();it!=s[x].end();it++){
ll y=(*it).first;
if(y==fa)continue;
ll w=f[y][1]-f[y][0]+(*it).second;
if(w<=0){S+=f[y][1]+(*it).second;siz--;continue;}
S+=f[y][0];q[x].Push(w);del.push(w);
}
while(q[x].Size()>max(siz-k,0ll)){
ll w=q[x].Top();
cl.push(w);
}
f[x][0]=S+q[x].sum;
while(q[x].Size()>max(siz-k-1,0ll)){
ll w=q[x].Top();
cl.push(w);
}
f[x][1]=S+q[x].sum;
while(!cl.empty())q[x].Push(cl.front()),cl.pop();
while(!del.empty())q[x].Pop(del.front()),del.pop();
return;
}
bool cmp(ll x,ll y)
{return deg[x]<deg[y];}
signed main(){
scanf("%lld",&n);
for(ll i=1;i<n;i++){
ll x,y,w;
scanf("%lld%lld%lld",&x,&y,&w);
addl(x,y,w);addl(y,x,w);
s[x].insert(mp(y,w));
s[y].insert(mp(x,w));
}
for(ll i=1;i<=n;i++)p[i]=i;
sort(p+1,p+n+1,cmp);
ll z=1;
memset(v,-1,sizeof(v));
for(ll k=0;k<n;k++){
if(k>=deg[p[n]]){
ans.push_back(0);
continue;
}
while(z<=n&°[p[z]]<=k){
ll x=p[z];
for(ll i=ls[x];i;i=a[i].next)
if(deg[a[i].to]>k){
q[a[i].to].Push(a[i].w);
s[a[i].to].erase(mp(x,a[i].w));
}
z++;
}
ll sum=0;
for(ll i=z;i<=n;i++)
if(v[p[i]]!=k)dfs(p[i],-1,k),sum+=f[p[i]][0];
ans.push_back(sum);
}
for(ll i=0;i<ans.size();i++)
printf("%lld ",ans[i]);
}
P7600-[APIO2021]封闭道路【堆,dp】的更多相关文章
- 【BZOJ-4524】伪光滑数 堆 + 贪心 (暴力) [可持久化可并堆 + DP]
4524: [Cqoi2016]伪光滑数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 183 Solved: 82[Submit][Status] ...
- 重建道路 树形DP
重建道路 树形DP 给一棵树,问最少断多少边使得这棵树树最终只有\(p\)个节点 设计dp状态\(f[u][i][j]\)表示节点\(u\),到第\(i\)个儿子,使\(j\)个节点分离,但是不分离 ...
- 洛谷 P1070 道路游戏 DP
P1070 道路游戏 题意: 有一个环,环上有n个工厂,每个工厂可以生产价格为x的零钱收割机器人,每个机器人在购买后可以沿着环最多走p条边,一秒走一条,每条边不同时间上出现的金币是不同的,问如何安排购 ...
- [BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案
考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情.. 先用dfs处理出来每个节点以他为根的子树的最长链和次长链.(后面会用到) 然后用类似dp ...
- bzoj2500幸福的道路 树形dp+单调队列
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 434 Solved: 170[Submit][Status][Discuss ...
- [HNOI2018]道路 --- 树形DP
[HNOI2018]道路 题目描述: W 国的交通呈一棵树的形状.W 国一共有 \(n-1\) 个城市和 \(n\) 个乡村, 其中城市从 \(1\) 到 \(n-1\) 编号,乡村从 \(1\) 到 ...
- JZYZOJ1525 HAOI2012道路 堆优化的dijkstra+pair
From Tyvj Guest ☆[haoi2012]道路 描述 Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当 ...
- 【bzoj2500】幸福的道路 树形dp+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
随机推荐
- CentOS7 安装Oracle19c数据库RPM包安装
我前两天发了安装oracle12c的方法,但是我虽然在虚拟机试验成功了,正式服务器安装的时候发现还是不行,安装页面卡空白,也没有解决办法,所以我就放弃了界面安装找命令行安装的办法,找了一些之后发现都比 ...
- Thread类的常用方法----多线程基础练习
创建多线程程序的第一种方式----继承Thread类 常用API 构造方法 public Thread() :分配一个新的线程对象. public Thread(String name) :分配一个指 ...
- 新东方集团K12公益免费课战役记
作者:张建鑫, 曾任IBM高级软件架构师, 滴滴高级技术专家, 现任新东方集团高级技术总监 1月31日,集团领导决定由产品技术中心的新东方APP团队牵头做周一到周五的集团公益课, 提供给全国中小学生使 ...
- 一次PHP大马提权
记一次PHP提权 发现 PHP大马:指木马病毒:PHP大马,就是PHP写的提取站点权限的程序:因为带有提权或者修改站点功能,所以称为叫木马. 自从师哥那里听说过之后,一直感叹于PHP大马的神奇...但 ...
- Spring BeanDefinition
定义 /** * A BeanDefinition describes a bean instance, which has property values, * constructor argume ...
- 20210821 打表,蛇,购物,ants
考场 T1 没看懂 T4 一眼回滚莫队,但忘记怎么写了,小慌 模拟 T1 题意的时候教练让 zsy 澄清了一下,确定了我不会做... T2 一看就是毒瘤题,T3 感觉比较可做 T4 确定了回滚的细节, ...
- ubantu硬盘不足,无法启动
我的ubantu虚拟机经过我一顿操作后,就起不来了.然后经过多方询问,广集天下良方,最终发现是由于分配的硬件空间不足导致的.现象如下: 通过查看 root@ubantu:/snap# df -h Fi ...
- echo -e 命令详解
echo在php中是输入那么在linux中是不是也是输入呢,当然echo在linux也是输入不过它的用法比php强大多了可以带参数及一些东西,下面我们来看一篇关于linux echo命令介绍及-n.- ...
- Linux-实战常用命令
目录 关机/重启/注销 系统信息和性能查看 磁盘和分区 ⽤户和⽤户组 ⽹络和进程管理 常⻅系统服务命令 ⽂件和⽬录操作 ⽂件查看和处理 打包和解压 RPM包管理命令 YUM包管理命令 DPKG包管理命 ...
- 硕盟USB3.0 转RJ45千兆网卡 TYPE A USB3.0 TO RJ45
硕盟SM-A44是一款USB3.0转RJ45千兆网口转换器.这是一种高性能和低开销的解决方案.转换USB端口到10 / 100/ 1000M以太网端口可以让您的笔记本,台式机电脑能够通过USB接口连接 ...