[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. 问每次操作只能通过将最后一个数拿出来 ...
随机推荐
- 数据库 'tempdb' 的事务日志已满。若要查明无法重用日志中的空间的原因
最常的做法: --1.清空日志 DUMP TRANSACTION tempdb WITH NO_LOG --2.截断事务日志: BACKUP LOG tempdb WITH NO_LOG --3.收缩 ...
- SLAM:(编译ORB)fatal error LNK1181: 无法打开输入文件“libboost_mpi-vc110-mt-1_57.lib”
对于使用MD版本编译的ORB_SLAM,会用到MPI版本的Boost,需要自己编译,比较麻烦. 因此使用MT版本进行生成,暂时无法完成. 工程配置 发现添加库文件使用了:从父级或项目默认继承,默认包含 ...
- Window8.1下安装Matplotlib库
有两种方法: 直接选用一些预打包库软件,如WinPython, Python(x,y), Enthought Canopy, or Continuum Anaconda.这些软件中已包含有Matplo ...
- chrome设置以及hosts备份
最近重装完chrome总是忘记改了哪些设置,所以这里做一下备份. 有卡顿问题可以关闭GPU加速 使用https的方式访问Google,Chrome下强制Google使用https的方法如下: 打开Ch ...
- Overview of Polymorphism -多态的分类
多态有类型系统衍生. 有限类型.无限类型.确定类型. Classifications Christopher Strachey (1967) introduced the concept of pol ...
- 从输入url到页面展示出来经历了哪些过程
本文只是一个整理向的随笔,以个人思路来简化的同时进行适当的拓展,如有错误,欢迎指正. 1.输入网址. 此时得到一个url 2.域名解析 整个过程都是dns系统在发挥作用,它的目的是将域名和ip对应起 ...
- 阿里云直播鉴权java代码示例
段时间公司需要做直播服务,所以就研究了一下阿里云的直播,在直播里面,最重要的就是url的鉴权操作(验证推流或者拉流的有效性),在网上找了很多代码,都没有发现java的demo,所以就写篇播客记录一下, ...
- php第十节课
数据访问 面向对象:类:由众多对象抽象出来的对象:由类实例化出来的,任何东西都可以看做对象来研究定义类:class 类名{ 成员变量 成员方法} 构造函数:写法特殊 执行特殊,对类里面的成员进行初始化 ...
- swift-UITableView的基本使用
废话不多说了,直接贴我今天写的代码吧:如果新手有什么不懂的,可以发我邮箱. // // singleInfo.swift 个人信息 // Housekeeper // // ...
- CentOS7.2安装nginx失败
错误提示: Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyu ...