[POI2011]Inspekcja

题目大意:

给你一棵\(n(n\le10^6)\)个点的树,\(s\)为起点。每次选择一个点作为目标点\(t_i\),沿最短路走到\(t_i\)再走回\(s\)(最后一次除外)。相邻两次行动不能经过相同的边。问将每一个点作为\(s\),是否存在一种方案使得除\(s\)外的所有结点都作为目标点被恰好访问一次,如果是,求最小路径和。

思路:

存在合法方案当且仅当去掉\(s\)后剩下的连通块中,最大的连通块大小不超过其余连通块大小之和。

这样的点一定是重心(反过来不一定),因此最多就不超过两个。

答案就是以这个点为根后所有点深度和×2-最大深度。

注意如果恰好有一个子树大小为\(\frac n2\),则最后删掉的深度一定在这棵子树中。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=1e6+1;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int n,size[N],max[N],dep[N],far[N];
void dfs1(const int &x,const int &par) {
size[x]=1;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs1(y,x);
size[x]+=size[y];
max[x]=std::max(max[x],size[y]);
}
max[x]=std::max(max[x],n-size[x]);
}
void dfs2(const int &x,const int &par) {
far[x]=0;
size[x]=1;
dep[x]=dep[par]+1;
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs2(y,x);
size[x]+=size[y];
far[x]=std::max(far[x],far[y]+1);
}
}
int main() {
n=getint();
max[0]=n+1;
dep[0]=-1;
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
dfs1(1,0);
for(register int x=1;x<=n;x++) {
if(max[x]>n/2) {
puts("-1");
continue;
}
dfs2(x,0);
int max=0;
int64 sum=0;
for(register int i=1;i<=n;i++) {
sum+=dep[i];
max=std::max(max,dep[i]);
}
for(register unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(size[y]==n/2) max=far[y]+1;
}
printf("%lld\n",sum*2-max);
}
return 0;
}

[POI2011]Inspekcja的更多相关文章

  1. BZOJ2527: [Poi2011]Meteors

    补一发题解.. 整体二分这个东西,一开始感觉复杂度不是很靠谱的样子 问了po姐姐,说套主定理硬干.. #include<bits/stdc++.h> #define ll long lon ...

  2. BZOJ2276: [Poi2011]Temperature

    2276: [Poi2011]Temperature Time Limit: 20 Sec  Memory Limit: 32 MBSubmit: 293  Solved: 117[Submit][S ...

  3. BZOJ2213: [Poi2011]Difference

    2213: [Poi2011]Difference Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 343  Solved: 108[Submit][St ...

  4. BZOJ2212: [Poi2011]Tree Rotations

    2212: [Poi2011]Tree Rotations Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 391  Solved: 127[Submi ...

  5. BZOJ 2212: [Poi2011]Tree Rotations( 线段树 )

    线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...

  6. bzoj 2217 [Poi2011]Lollipop 乱搞 贪心

    2217: [Poi2011]Lollipop Time Limit: 15 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 383  Solved ...

  7. BZOJ_2529_[Poi2011]Sticks_贪心

    BZOJ_2529_[Poi2011]Sticks_贪心 Description Little Johnny was given a birthday present by his grandpare ...

  8. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

  9. BZOJ_2527_[Poi2011]Meteors_整体二分

    BZOJ_2527_[Poi2011]Meteors_整体二分 Description Byteotian Interstellar Union (BIU) has recently discover ...

随机推荐

  1. git命令行工作环境配置【转】

    转自:http://www.cocoachina.com/ios/20171115/21163.html 本文为CocoaChina网友whf5566投稿 前言 笔者一直使用git的图形化工具sour ...

  2. dubbo系列二、dubbo+zookeeper+dubboadmin分布式服务框架搭建(windows平台)

    一.zookeeper配置中心安装 1.下载安装包,zookeeper-3.4.6.tar.gz 2.解压安装包,修改配置文件 参考zookeeper-3.4.6/conf/zoo_sample.cf ...

  3. Innodb ,MyISAM

    1. InnoDB不支持FULLTEXT类型的索引. 2. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算 ...

  4. Python poll IO多路复用

    一.poll介绍 poll本质上和select没有区别,只是没有了最大连接数(linux上默认1024个)的限制,原因是它基于链表存储的. 本人的另一篇博客讲了 python  select : ht ...

  5. python的MD5

    import hashlib def md5(str0): hl = hashlib.md5()# 创建md5对象 hl.update(str0.encode(encoding='utf-8'))#此 ...

  6. 虚拟机Ubuntu 18.04安装RabbitMQ 3.7.9

    Windows 10家庭中文版,VirtualBox,Ubuntu 18.04,Rabbitmq 3.7.9,Erlang/OTP 20 [erts-9.2], 在虚拟机上装好了Ubuntu,写了一个 ...

  7. 洛谷p1072 gcd,质因数分解

    /* 可以得a>=c,b<=d,枚举d的质因子p 那么a,b,c,d,x中包含的p个数是ma,mb,mc,md,mx 在gcd(a,x)=c中 ma<mc => 无解 ma=m ...

  8. 知识点:从迭代器一直撸到yield from

    最近在跟一个系列, 难度和篇幅比较合适我这样的懒人. 敲下代码,作下注释,看看输出,就蛮好. https://www.cnblogs.com/wongbingming/p/9095243.html i ...

  9. POJ 1742 Coins 【多重背包DP】

    题意:有n种面额的硬币.面额.个数分别为A_i.C_i,求最多能搭配出几种不超过m的金额? 思路:dp[j]就是总数为j的价值是否已经有了这种方法,如果现在没有,那么我们就一个个硬币去尝试直到有,这种 ...

  10. 【BZOJ5110】[CodePlus2017]Yazid 的新生舞会

    题解: 没笔的时候我想了一下 发现如果不是出现一半次数而是k次,并不太会做 然后我用前缀和写了一下发现就是维护一个不等式: 于是就可以随便维护了