【LOJ6042】「雅礼集训 2017 Day7」跳蚤王国的宰相(思博题)
大致题意: 给你一棵树,询问对于每个点需要改变多少条边来使得它成为树中到所有点距离和最小的点。
一些初始化及想法
这是一道思博题。
首先我们要知道一个结论:对于这棵树的重心,它的答案必定为\(0\)。
然后对于非重心的点该怎么办呢?
我们考虑把重心作为根,并统计出每个子节点的\(Size\)。
接下来我们可以发现,如果割掉根节点的若干棵子树,且这些子树\(Size\)和\(\ge\frac n2\),那么肯定就可以构造出一种合法的方案使得任意节点符合条件。
由于要割的次数最少,因此我们将根节点的子节点按\(Size\)从大到小排序,然后取尽量少的节点使得\(Size\)和\(\ge\frac n2\),并记录所需节点数为\(p\)。
答案的取值
对于除重心外的每个点,其答案只可能为\(p\)或者\(p-1\)。
什么时候能够取\(p-1\)呢?
假设一个点\(x\)位于根节点的子节点排序后的第\(i\)个子节点的子树内。
对于\(i\le p\),我们割去除\(i\)外第\(1\sim p\)个点到根节点的连边。如果这些被割去的子树的\(Size\)和加上\(Size_x\ge\frac n2\),那么我们就不需要再割一条新边了。
而对于\(i>p\)的情况也是类似的,只不过一开始割去的是第\(1\sim p-1\)个点到根节点的连边。
按照这样的方式,我们就可以求出答案了。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define INF 1e9
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
#define max(x,y) ((x)>(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
using namespace std;
int n,p,rt,cnt,ee,s[N+5],lnk[N+5],Sz[N+5],Mx[N+5],ans[N+5];struct edge {int to,nxt;}e[N<<1];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C^FS?FO[C++]=c:(fwrite(FO,1,C,stdout),FO[(C=0)++]=c))
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T,C;char c,*A,*B,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
Tp I void writeln(Con Ty& x) {write(x),pc('\n');}
I void clear() {fwrite(FO,1,C,stdout),C=0;}
}F;
I void GetRt(CI x,CI lst=0)//求重心
{
for(RI i=(Sz[x]=1,Mx[x]=0,lnk[x]);i;i=e[i].nxt) e[i].to^lst&&
(GetRt(e[i].to,x),Sz[x]+=Sz[e[i].to],Gmax(Mx[x],Sz[e[i].to]));
Gmax(Mx[x],n-Sz[x]),Mx[x]<Mx[rt]&&(rt=x);
}
I void Init(CI x,CI lst=0)//初始化Size
{
for(RI i=(Sz[x]=1,lnk[x]);i;i=e[i].nxt)
e[i].to^lst&&(Init(e[i].to,x),Sz[x]+=Sz[e[i].to]);
}
I void GetAns(CI x,CI lst,CI v)//求解答案
{
ans[x]=p,(Sz[x]+v<<1)>=n&&--ans[x];//判断答案是否可以减1
for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&(GetAns(e[i].to,x,v),0);//遍历子树
}
I bool cmp(CI x,CI y) {return Sz[x]>Sz[y];}//按Size排序
int main()
{
RI i,x,y;for(F.read(n),i=1;i^n;++i) F.read(x,y),add(x,y),add(y,x);//读入+建边
for(Mx[rt=0]=INF,GetRt(1),Init(rt),cnt=0,i=lnk[rt];i;i=e[i].nxt) s[++cnt]=e[i].to;//找到重心,将重心儿子存下来用于排序
for(sort(s+1,s+cnt+1,cmp),x=0,i=1;i<=cnt&&(x<<1)<n;++i) x+=Sz[s[i]];p=i-1;//排序,然后求出p
for(i=1;i<=cnt;++i) GetAns(s[i],rt,x-max(Sz[s[i]],Sz[s[p]]));//枚举子节点处理答案
for(i=1;i<=n;++i) F.writeln(ans[i]);return F.clear(),0;//输出
}
【LOJ6042】「雅礼集训 2017 Day7」跳蚤王国的宰相(思博题)的更多相关文章
- 「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心)
题面 来源 「 雅 礼 集 训 2017 D a y 7 」 跳 蚤 王 国 的 宰 相 传 统 2000 m s 1024 M i B {\tt「雅礼集训 2017 Day7」跳蚤王国的 ...
- LOJ #6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相
我可以大喊一声这就是个思博题吗? 首先如果你能快速把握题目的意思后,就会发现题目就是让你求出每个点要成为树的重心至少要嫁接多少边 先说一个显然的结论,重心的答案为\(0\)(废话) 然后我们考虑贪心处 ...
- 【思维题 细节】loj#6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相
挂于±1的细节…… 题目描述 跳蚤王国爆发了一场动乱,国王在镇压动乱的同时,需要在跳蚤国地方钦定一个人来做宰相. 由于当时形势的复杂性,很多跳蚤都并不想去做一个傀儡宰相,带着宰相的帽子,最后还冒着被打 ...
- 「雅礼集训 2017 Day7」事情的相似度
「雅礼集训 2017 Day7」事情的相似度 题目链接 我们先将字符串建后缀自动机.然后对于两个前缀\([1,i]\),\([1,j]\),他们的最长公共后缀长度就是他们在\(fail\)树上对应节点 ...
- 【LOJ 6041】「雅礼集训 2017 Day7」事情的相似度
Description 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的 ...
- 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度
题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...
- LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度
我可以大喊一声这就是个套路题吗? 首先看到LCP问题,那么套路的想到SAM(SA的做法也有) LCP的长度是它们在parent树上的LCA(众所周知),所以我们考虑同时统计多个点之间的LCA对 树上问 ...
- loj#6041. 「雅礼集训 2017 Day7」事情的相似度(SAM set启发式合并 二维数点)
题意 题目链接 Sol 只会后缀数组+暴躁莫队套set\(n \sqrt{n} \log n\)但绝对跑不过去. 正解是SAM + set启发式合并 + 二维数点/ SAM + LCT 但是我只会第一 ...
- LOJ #6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案
我可以大喊一声这就是个SB题吗? 首先讲一句如果你像神仙CXR一样精通搜索你就可以得到\(80pts\)(无Subtask)的好成绩 我们考虑挖掘一下题目的性质,首先发现这是一个置换,那么我们发现这的 ...
随机推荐
- PIE SDK文本元素的绘制
1. 功能简介 在数据的处理中会用到文本元素的绘制,利用ITextElement文本元素接口进行绘制,目前PIE SDK支持ITextSymbol符号接口,TextSymbol对象是用于修饰文字元素对 ...
- fixed
之前我们见的fixed就是固定在低端.后来我遇到一个问题 如果 这样写: div{ position: fixed; left: 0; bottom: 0; } 内容吧div撑开,有多少算多少 di ...
- iView 初识
iView和element-UI在table这块有有相似之处,但是与layui有不同的地方 在data数据这里有明显的不同,在iView中data数组下每个元素对象对应一行的数据:而layui中,da ...
- 解决matplotlib绘图中文乱码
# 指定默认字体 下面三条代码用来解决绘图中出现的乱码 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams[ ...
- MAYA 卸载工具,完美彻底清除干净maya各种残留注册表和文件
是不是遇到MAYA/CAD/3DSMAX/INVENTOR安装失败?AUTODESK系列软件着实令人头疼,MAYA/CAD/3DSMAX/INVENTOR安装失败之后不能完全卸载!!!(比如maya, ...
- day07 - Python - 面向对象进阶
本节内容: 面向对象高级语法部分异常处理异常处理异常处理 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 1 ...
- Ace教你一步一步做Android新闻客户端(四) 优化Bitmap大法
我计划着把需要用到的知识分解开来写,趁着我们要开发这款客户端的机会把安卓所有移动客户端开发中的技术贯穿其中,也是我自己成长的过程.By Ace in 20160121 我们开发一款新闻客户端程序,它的 ...
- Where Should an Architect Begin?--reference
http://www.bitnative.com/2014/01/24/where-should-a-software-architect-begin/ Where Should an Archite ...
- mysql用户操作
一, 创建用户: 命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指 ...
- Java入门系列-07-从控制台中接收输入
这篇文章帮你使用Scanner类从控制台接收输入 从控制台接收字符串 敲一敲: import java.util.Scanner; public class DemoScanner { public ...