CF1119F Niyaz and Small Degrees【treedp+堆】
如果枚举d来dp,那么就是设f[u][0/1]为u点不断/断掉和父亲的边,然后优先选取f[v][1]+w(u,v)<=f[v][0]的,如果断掉这些度数还是多就用一个堆维护剩下的按f[v][1]+w(u,v)-f[v][0]从大到小取(负的)
然后注意到设当前要求度数是d,那么度数<=d的点全都不用dp,所以可以直接把贡献累加到和他相邻的点上然后断掉边,这样一共算Σ度数ci,就是O(nlogn)的了
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N=300005;
int n,du,v[N],d[N],s[N],ne[N];
long long ans,sm[N],f[N][2];
vector<pair<int,int> >e[N];
vector<int>a[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
struct dui
{
priority_queue<long long>p,q;
void push(long long x)
{
q.push(x);
}
void erase(long long x)
{
p.push(x);
}
int top()
{
while(!q.empty()&&!p.empty()&&q.top()==p.top())
q.pop(),p.pop();
return q.top();
}
void pop()
{
top();
q.pop();
}
int size()
{
return q.size()-p.size();
}
bool empty()
{
return q.size()==p.size();
}
}q[N];
bool cmp(const pair<int,int>&a,const pair<int,int>&b)
{
return d[a.first]<d[b.first];
}
void add(int u,int v,int w)
{
e[u].push_back(make_pair(v,w));
e[v].push_back(make_pair(u,w));
}
void dfs(int u,int fa)
{
v[u]=1;
int r=d[u]-du;
long long sum=0;
vector<long long>ad,de;
while(q[u].size()>r)
sm[u]-=q[u].top(),q[u].pop();
while(s[u]<e[u].size()&&d[e[u][s[u]].first]<=du)
s[u]++;
for(int i=s[u],len=e[u].size();i<len;i++)
if(!v[e[u][i].first]&&e[u][i].first!=fa)
{
dfs(e[u][i].first,u);
if(f[e[u][i].first][1]+e[u][i].second<=f[e[u][i].first][0])
r--,sum+=f[e[u][i].first][1]+e[u][i].second;
else
{
sum+=f[e[u][i].first][0];
long long nw=f[e[u][i].first][1]+e[u][i].second-f[e[u][i].first][0];
q[u].push(nw);
sm[u]+=nw;
de.push_back(nw);
}
}
while(q[u].size()>max(0,r))
sm[u]-=q[u].top(),ad.push_back(q[u].top()),q[u].pop();
f[u][0]=sum+sm[u];
r--;
while(q[u].size()>max(0,r))
sm[u]-=q[u].top(),ad.push_back(q[u].top()),q[u].pop();
f[u][1]=sum+sm[u];
for(int i=0,len=ad.size();i<len;i++)
q[u].push(ad[i]),sm[u]+=ad[i];
for(int i=0,len=de.size();i<len;i++)
q[u].erase(de[i]),sm[u]-=de[i];
}
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z);
d[x]++,d[y]++;
ans+=z;
}
for(int i=1;i<=n;i++)
{
a[d[i]].push_back(i);
sort(e[i].begin(),e[i].end(),cmp);
}
ne[n]=n+1;
for(int i=n-1;i>=1;i--)
{
if(a[i+1].size())
ne[i]=i+1;
else
ne[i]=ne[i+1];
}
printf("%lld ",ans);
for(int i=1;i<n;i++)
{
for(int j=0,len=a[i].size(),u;j<len;j++)
{
u=a[i][j];
v[u]=1;
for(int k=0,le=e[u].size();k<le;k++)
if(!v[e[u][k].first])
q[e[u][k].first].push(e[u][k].second),sm[e[u][k].first]+=e[u][k].second;
}
ans=0,du=i;
for(int j=i+1;j<=n;j=ne[j])
for(int k=0,len=a[j].size();k<len;k++)
if(!v[a[j][k]])
{
dfs(a[j][k],0);
ans+=f[a[j][k]][0];
}
for(int j=i+1;j<=n;j=ne[j])
for(int k=0,len=a[j].size();k<len;k++)
v[a[j][k]]=0;
printf("%lld ",ans);
}
return 0;
}
CF1119F Niyaz and Small Degrees【treedp+堆】的更多相关文章
- CF1119F Niyaz and Small Degrees
题意 给你\(n\)个点的树,边有边权 问使得所有的点度数都小于等于\(x\)的最小删边的代价 \([x \in 0...n-1]\) 题解 首先对于每个\(x\) 可以有一个\(O(nlogn)\) ...
- 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案
Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...
- [codeforces contest 1119 F] Niyaz and Small Degrees 解题报告 (树形DP+堆)
interlinkage: http://codeforces.com/contest/1119/problem/F description: 有一颗$n$个节点的树,每条边有一个边权 对于一个$x$ ...
- 【codeforces contest 1119 F】Niyaz and Small Degrees
题目 描述 \(n\) 个点的树,每条边有一个边权: 对于一个 \(X\) ,求删去一些边后使得每个点的度数 \(d_i\) 均不超过 \(X\) 的最小代价: 你需要依次输出 \(X=0 \to n ...
- CF 1119F Niyaz and Small Degrees
打VP的时候由于CXR和XRY切题太快了导致我只能去写后面的题了 然而VP的时候大概还有一小时时想出了\(O(n^2\log n)\)的暴力,然后过了二十分钟才想到删点的优化 结果细节很多当然是写不出 ...
- Solution -「CF 1119F」Niyaz and Small Degrees
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个结点的树,边有边权,对于每个整数 \(x\in[0,n)\),求出最少的删边代价使得任意结点度数不超过 ...
- Codeforces Global Round 2 Solution
这场题目设置有点问题啊,难度:Div.2 A->Div.2 B->Div.2 D->Div.2 C->Div.2 D->Div.1 D-> Div.1 E-> ...
- Codeforces Global Round 2 部分题解
F.Niyaz and Small Degrees 挺sb的一题,为什么比赛时只过了4个呢 考虑当\(x\)固定的时候怎么做.显然可以树形DP:设\(f_{u,i=0/1}\)表示只考虑\(u\)子树 ...
- P7600-[APIO2021]封闭道路【堆,dp】
正题 题目链接:https://www.luogu.com.cn/problem/P7600 题目大意 给出\(n\)个点的一棵树,边有边权,对于每个\(k\)求去掉最小边权和的点使得每个点的度数都不 ...
随机推荐
- SAP-Function
[转]sap函数大全 ********SAP中常用函数 函数名 描述SD_VBAP_READ_WITH_VBELN 根据销售订单读取表vbap中的信息EDIT_LINES 把READ_TEXT返回的L ...
- Mysql 外键级联
如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...
- Swift 烧脑体操(二) - 函数的参数
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- UEditor上传文件的默认地址修改
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text.Re ...
- The Contiki build system
The Contiki build system http://contiki.sourceforge.net/docs/2.6/a01796.html 先看官方文档的说明,对contiki的构建系统 ...
- hello vue不显示
本身是做java后端开发的,但对任何技术都感兴趣.于是尝试了下最近国内比较火的vue框架. 在使用官网的例的时候子就卡壳了,写了个html,第一个Hello VUE!就是出不来,只显示{{messag ...
- PYTHON 爬虫笔记十:利用selenium+PyQuery实现淘宝美食数据搜集并保存至MongeDB(实战项目三)
利用selenium+PyQuery实现淘宝美食数据搜集并保存至MongeDB 目标站点分析 淘宝页面信息很复杂的,含有各种请求参数和加密参数,如果直接请求或者分析Ajax请求的话会很繁琐.所以我们可 ...
- Linux-DHCP服务器的搭建
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)通常被应用在大型的局域网络环境中,主要作用是集中的管理.分配IP地址,使网络环境中的主机动态的获得I ...
- BZOJ 4582 [Usaco2016 Open]Diamond Collector:贪心【相差不超过k】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4582 题意: 给你n个数. 让你将其中的一些数放入两个不同的集合中,并保证同一集合内两两元 ...
- HDU 2157 How many ways??:矩阵快速幂【i到j共经过k个节点的方法数】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2157 题解: 给你一个有向图,n个节点m条边,问你从i到j共经过k个节点的方法数(不算i点). 题解: ...