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+堆)的更多相关文章

  1. 【codeforces contest 1119 F】Niyaz and Small Degrees

    题目 描述 \(n\) 个点的树,每条边有一个边权: 对于一个 \(X\) ,求删去一些边后使得每个点的度数 \(d_i\) 均不超过 \(X\) 的最小代价: 你需要依次输出 \(X=0 \to n ...

  2. 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案

    Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...

  3. 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 ...

  4. Codeforces Round #551 (Div. 2) D. Serval and Rooted Tree (树形dp)

    题目:http://codeforces.com/contest/1153/problem/D 题意:给你一棵树,每个节点有一个操作,0代表取子节点中最小的那个值,1代表取子节点中最大的值,叶子节点的 ...

  5. Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形dp)

    http://codeforces.com/contest/816/problem/E 题意: 去超市买东西,共有m块钱,每件商品有优惠卷可用,前提是xi商品的优惠券被用.问最多能买多少件商品? 思路 ...

  6. 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 ...

  7. 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)

    官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/ 表 ...

  8. codeforces 519C. A and B and Team Training 解题报告

    题目链接:http://codeforces.com/contest/519/problem/C 题目意思:给出 n 个  experienced participants  和 m 个 newbie ...

  9. codeforces 454B. Little Pony and Sort by Shift 解题报告

    题目链接:http://codeforces.com/problemset/problem/454/B 题目意思:给出一个序列你 a1, a2, ..., an. 问每次操作只能通过将最后一个数拿出来 ...

随机推荐

  1. 【PostgreSQL-9.6.3】修改监听的IP和端口

    在数据目录下编辑postgresql.conf文件,我的数据目录是/usr/local/pgsql/data vi postgresql.conf 找到如下内容: ... #listen_addres ...

  2. WinXP SSH连接不上虚拟机的解决方法

    问题现象描述: 在VMWare中安装好linux系统后,选择桥接,从宿主机Windows上使用Putty, SSH Secure Shell等客户端工具连接linux上的ssh服务,客户端一直没有反应 ...

  3. windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案(转)

    戴尔服务器r530 windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案 关于在服务 ...

  4. (转)基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用

    http://www.cnblogs.com/wuhuacong/p/4774396.html Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使 ...

  5. 怎样批量删除PDF文件中的注释

    日常我们在阅读一些PDF文章时候,我们会发现有些PDF文章带有非常多的注释,显得非常不美观,影响了阅读体验.那么PDF文章里的批注应该怎么进行删除呢?怎样批量删除PDF文件中的注释?   操作教程: ...

  6. C# --MVC实现简单上传下载

    首先创建一个默认的控制器Defaultcontroller 然后生成视图View 在视图里面 创建文件选择器 创建上传.下载按钮 代码如下 <body> <div> <f ...

  7. react构建前端项目方法汇总

    react简介: 一.使用react 创建一个PC端的项目 (a):使用 yemon 创建一个 webpack 的 react 的项目 控制台安装并且产看 yemon 的版本 yo -v (b): 全 ...

  8. icheck使用

    1.使用: <link rel="stylesheet" href="css/skins/all.css">或者<link rel=" ...

  9. BZOJ 3510: 首都 LCT + multiset维护子树信息 + 树的重心

    Code: #include<bits/stdc++.h> #define maxn 200000 #define inf 1000000000 using namespace std; ...

  10. ansible-galera集群部署(13)

    一.环境准备 1.各主机配置静态域名解析: [root@node1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain local ...