[codeforces contest 1119 F] Niyaz and Small Degrees 解题报告 (树形DP+堆)
interlinkage:
http://codeforces.com/contest/1119/problem/F
description:

有一颗$n$个节点的树,每条边有一个边权
对于一个$x$,删去一些边使得每个点的度数都不超过$x$,最小化删去边的边权并输出
需要一次输出$x=0->n-1$的值
$1<=n<=250000$
solution:
- part1
- 先考虑单个$x$的做法。任选一个根,设$f_{u,0/1}$表示以节点$u$为根的子树内,节点$u$与它的父亲不断/断的最小代价;
- 显然这个可以讨论转移,但我们换一个更好的角度;
- 设$v$为$u$的一个儿子,若$f_{v,1}+c<=f_{v,0}$,即断的话比不断更优秀的,那么我们一定选择断,因为这样还可以让$u$的度数小$1$。这种情况我们就直接加上$f_{v,1}+c$,并让$u$度数$--$;
- 否则的话我们就先假设这条边不断,加上$f_{v,0}$。那么到最后可能会发现$u$的度数不满足不超过$x$,显然我们要把若干个$f_{v,0}$变成$f_{v,1}+c$;
- 我们对每个点维护一个$f_{v,1}+c-f_{v,0}$的堆,取度数-$x$个最小的就好了;
- 这里的堆本质上维护的就是通过多大的代价能让度数减一;
- part2
- 现在考虑多个$x$,从小做到大
- 有一个很显然的想法,若是一个点原来的度数就不超过$x$,那么这个点可以直接删掉;
- 做法是把所有以这个点为端点的边放到这些边的另一个端点的堆里面,表示可以通过断掉这条边来使得度数减一;
- 剩下的就是对所有有用的点,即度数大于$x$的点做上面的$DP$就好了;
- part3
- 复杂度显然为$\sum_{x=0}^{n-1}\sum_{i=1}^{n}[du_i>x]=\sum_{i=1}^{n}du_i=O(n)$;
code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll; const ll N=;
ll n;
ll du[N],nxt[N],vis[N];
ll sum[N];
vector <pll> e[N];
vector <ll> d[N];
inline ll read()
{
char ch=getchar();ll s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
bool cmp(pll x,pll y) {return du[x.fi]<du[y.fi];}
struct node
{
priority_queue <ll> A,B;
void push(ll x) {A.push(x);}
void del(ll x) {B.push(x);}
ll top() {while (!B.empty()&&A.top()==B.top()) A.pop(),B.pop();return A.top();}
void pop() {top();A.pop();}
ll size() {return A.size()-B.size();}
}h[N];
void upd(ll x,ll num)
{
while (h[x].size()>num)
{
sum[x]=sum[x]-h[x].top();
h[x].pop();
}
}
void upd1(ll x,ll num,vector <ll> &add)
{
while (h[x].size()>num)
{
sum[x]=sum[x]-h[x].top();
add.pb(h[x].top());
h[x].pop();
}
}
void dele(ll x)
{
vis[x]=;
for (ll i=;i<e[x].size();i++)
{
ll y=e[x][i].fi,c=e[x][i].se;;
if (vis[y]) continue;
h[y].push(c);sum[y]=sum[y]+c;
}
}
ll D;
ll f[N][],st[N];
void dfs(ll x)
{
vis[x]=;ll num=du[x]-D;
upd(x,num);
vector <ll> add,del;
add.clear();del.clear();
ll siz=e[x].size(),tot=;
while (st[x]<siz&&du[e[x][st[x]].fi]<=D) st[x]++;
for (ll i=st[x];i<siz;i++)
{
ll y=e[x][i].fi,c=e[x][i].se;;
if (vis[y]) continue;
dfs(y);
if (f[y][]+c<=f[y][]) {num--;tot=tot+f[y][]+c;}
else
{
tot=tot+f[y][];
ll o=f[y][]+c-f[y][];
del.pb(o);
h[x].push(o);
sum[x]=sum[x]+o;
}
}
upd1(x,max(0ll,num),add);
f[x][]=tot+sum[x];
upd1(x,max(0ll,num-),add);
f[x][]=tot+sum[x];
for (ll i=;i<add.size();i++) h[x].push(add[i]),sum[x]+=add[i];
for (ll i=;i<del.size();i++) h[x].del(del[i]),sum[x]-=del[i];
}
int main()
{
n=read();
ll ans=;
for (ll i=;i<n;i++)
{
ll x=read(),y=read(),c=read();
e[x].pb({y,c});e[y].pb({x,c});
du[x]++;du[y]++;
ans+=c;
}
printf("%I64d ",ans);
for (ll i=;i<=n;i++)
{
d[du[i]].pb(i);
sort(e[i].begin(),e[i].end(),cmp);
}
nxt[n]=n+;
for (ll i=n-;i>=;i--)
{
if (d[i+].size()) nxt[i]=i+;
else nxt[i]=nxt[i+];
}
memset(vis,,sizeof(vis));
for (ll u=;u<n;u++)
{
for (ll i=;i<d[u].size();i++) dele(d[u][i]);
ans=;D=u;
for (ll i=u+;i<n;i=nxt[i])
for (ll j=;j<d[i].size();j++)
{
if (vis[d[i][j]]) continue;
dfs(d[i][j]);
ans=ans+f[d[i][j]][];
}
for (ll i=u+;i<n;i=nxt[i])
for (ll j=;j<d[i].size();j++) vis[d[i][j]]=;
printf("%I64d ",ans);
}
return ;
}
[codeforces contest 1119 F] Niyaz and Small Degrees 解题报告 (树形DP+堆)的更多相关文章
- 【codeforces contest 1119 F】Niyaz and Small Degrees
题目 描述 \(n\) 个点的树,每条边有一个边权: 对于一个 \(X\) ,求删去一些边后使得每个点的度数 \(d_i\) 均不超过 \(X\) 的最小代价: 你需要依次输出 \(X=0 \to n ...
- 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案
Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...
- Codeforces Round #384 (Div. 2)D - Chloe and pleasant prizes 树形dp
D - Chloe and pleasant prizes 链接 http://codeforces.com/contest/743/problem/D 题面 Generous sponsors of ...
- Codeforces Round #551 (Div. 2) D. Serval and Rooted Tree (树形dp)
题目:http://codeforces.com/contest/1153/problem/D 题意:给你一棵树,每个节点有一个操作,0代表取子节点中最小的那个值,1代表取子节点中最大的值,叶子节点的 ...
- Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形dp)
http://codeforces.com/contest/816/problem/E 题意: 去超市买东西,共有m块钱,每件商品有优惠卷可用,前提是xi商品的优惠券被用.问最多能买多少件商品? 思路 ...
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
Colorful Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)
官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/ 表 ...
- codeforces 519C. A and B and Team Training 解题报告
题目链接:http://codeforces.com/contest/519/problem/C 题目意思:给出 n 个 experienced participants 和 m 个 newbie ...
- codeforces 454B. Little Pony and Sort by Shift 解题报告
题目链接:http://codeforces.com/problemset/problem/454/B 题目意思:给出一个序列你 a1, a2, ..., an. 问每次操作只能通过将最后一个数拿出来 ...
随机推荐
- Linux通信之同步阻塞模式
[参考]韦东山 教学笔记 1. 原子操作原子操作指的是在执行过程中不会被别的代码路径所中断的操作.常用原子操作函数举例:atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初 ...
- Excel的用到的常规的技巧
这几天在做各种发票的报表,好几百的数据当然离不开EXCel,自己又是个白班,就记录下啦! EXCEL 判断某一单元格值是否包含在某一列中 就在Excel的表格中加入这个函数:=IF(ISERROR(V ...
- 【sqli-labs】 less26 GET- Error based -All you SPACES and COMMENTS belong to us(GET型基于错误的去除了空格和注释的注入)
看了下源码 所有的注释形式和反斜线,and,or都被了过滤掉了 单引号没有过滤 空格也被过滤了 http://localhost/sqli-labs-master/Less-26/?id=1' htt ...
- vue路由中的 Meta
在项目中肯定有这样的需求,那就是在某个页面的时候,顶部展示 现在当前的页面路径,如下图: 这个在vue中其实很好实现. 首先出现这个肯定是相对应不同的页面,也就是说对应不同的路由,我们在定义路由的时候 ...
- [转载]windows下github 出现Permission denied (publickey).解决方法
今天在学习github的时候遇到了一些问题,然后爬了一会,找到了解决方法记录下来,以防忘记,当然能帮助别人最好啦! github教科书传送门:http://www.liaoxuefeng.com/ ...
- Lua的五种变量类型、局部变量、全局变量、lua运算符、流程控制if语句_学习笔记02
Lua的五种变量类型.局部变量.全局变量 .lua运算符 .流程控制if语句 Lua代码的注释方式: --当行注释 --[[ 多行注释 ]]-- Lua的5种变量类型: 1.null 表示 ...
- PHP第一节课
基础语法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)
题面传送门 题目大意:给你一个序列,多次询问,每次取出一段连续的子序列$[l,r]$,询问这段子序列的逆序对个数,强制在线 很熟悉的分块套路啊,和很多可持久化01Trie的题目类似,用分块预处理出贡献 ...
- [bzoj3029] 守卫者的挑战 (概率期望dp)
传送门 Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过."我,Nizem,是黑魔法圣殿的守 ...
- SOA架构设计的案例分析
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来.接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台. ...