题目描述:

ydc有一棵n个结点的黑白相间的大树,从1到n编号。

这棵黑白树中有m个黑点,其它都是白点。

对于一个黑点我们定义他的好朋友为离他最远的黑点。如果有多个黑点离它最远那么都是它的好朋友。两点间的距离定义为两点之间的最短路的长度。

现在你要摧毁一个白点。

摧毁后有一些黑点会不高兴。一个黑点不高兴当且仅当他不能到达任何一个在摧毁那个白点前的好朋友。

请你最大化不高兴的黑点数。

解题报告:

套路题啊,直接提黑点重心到根,那么这样就可以保证每一个黑点到其最远的黑点一定经过根节点了,那么就可以开始枚举白点并讨论。

首先白点的子树内的黑点都是被截断的,然后考虑其是否在到根最长路和次长路上:

如果有三个及以上最长路显然是无法截断的。

如果仅有两个及以下,那么如果在最长路上,且最长路唯一,那么除了该子树内最长路所在子树外的所有黑点一定都能被截断。

如果是在次长路上,那么最长路上的黑点就要走到次长路上,一定会被截断

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=1e5+5;
int num=0,head[N],nxt[N<<1],to[N<<1],dis[N<<1],n,m;bool col[N];
void link(int x,int y,int z){nxt[++num]=head[x];to[num]=y;dis[num]=z;head[x]=num;}
int root=0,f[N],g[N],bel[N],sz[N];
void getroot(int x,int last,int *p){
int u;if(col[x] && p[root]<p[x])root=x;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==last)continue;
p[u]=p[x]+dis[i];
getroot(u,x,p);
}
}
void dfs(int x,int last,int dist){
int u;
if(last==root)bel[x]=x;
else bel[x]=bel[last];
sz[x]=col[x];
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==last)continue;
dfs(u,x,dist+dis[i]);
sz[x]+=sz[u];
}
if(sz[x]){
f[x]=dist;g[x]=1;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==last)continue;
if(f[u]>f[x]){f[x]=f[u];g[x]=g[u];}
else if(f[x]==f[u])g[x]+=g[u];
}
}
}
void work()
{
int x,y,z;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){scanf("%d",&x);col[x]=true;}
for(int i=1;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
link(x,y,z);link(y,x,z);
}
root=0;getroot(1,1,f);
x=root;root=0;getroot(x,x,g);
memset(f,0,sizeof(f));
getroot(root,root,f);root=0;
for(int i=1;i<=n;i++)
if(g[i]+f[i]==f[x]){
if(!root)root=i;
else if(abs(f[i]-g[i])<abs(f[root]-g[root]))root=i;
}
for(RG int i=0;i<N;i++)f[i]=g[i]=0;
dfs(root,root,0);
int mx=0,cmx=0,mxid=0,cmxid=0,ans=0,answer=0,tot=0,mxcnt=0;
if(!col[root])ans=m,answer=1;
for(int i=head[root];i;i=nxt[i]){
int u=to[i];if(!sz[u])continue;
if(f[u]>mx){cmx=mx;cmxid=mxid;mx=f[u];mxid=u;mxcnt=0;}
else if(f[u]==mx){
if(f[mxid]==f[cmxid]){mxid=0;cmxid=0;mxcnt=3;}
else{cmxid=mxid;cmx=mx;mxid=u;mx=f[u];}
}
else if(f[u]>cmx){cmxid=u;cmx=f[u];mxcnt=0;}
}
if(mxcnt==3)mxid=0,cmxid=0;
for(int i=1;i<=n;i++){
if(col[i]==1 || i==root)continue;
tot=sz[i];
if(tot && f[i]==f[bel[i]] && g[i]==g[bel[i]]){
if(bel[i]==mxid){
if(f[mxid]!=f[cmxid])tot+=m-sz[mxid];
else tot+=sz[cmxid];
}
else if(bel[i]==cmxid)tot+=sz[mxid];
}
if(tot>ans){ans=tot;answer=1;}
else if(ans==tot)answer++;
}
printf("%d %d\n",ans,answer);
}
int main(){work();return 0;}

UOJ #11. 【UTR #1】ydc的大树的更多相关文章

  1. 【UTR #1】ydc的大树

    [UTR #1]ydc的大树 全网唯一一篇题解我看不懂 所以说一下我的O(nlogn)做法: 以1号点为根节点 一个黑点如果有多个相邻的节点出去都能找到最远的黑点,那么这个黑点就是无敌的 所以考虑每个 ...

  2. UOJ #11 - 【UTR #1】ydc的大树(换根 dp)

    题面传送门 Emmm--这题似乎做法挺多的,那就提供一个想起来写起来都不太困难的做法吧. 首先不难想到一个时间复杂度 \(\mathcal O(n^2)\) 的做法:对于每个黑点我们以它为根求出离它距 ...

  3. uoj problem 11 ydc的大树

    题目大意: 给定一颗黑白树.允许删除一个白点.最大化删点后无法与删点前距自己最远的黑点连通的黑点个数.并求出方案数. 题解: 这道题很棒棒啊. 一开始想了一个做法,要用LCT去搞,特别麻烦而且还是\( ...

  4. Codeforces-348E Pilgrims

    #4342. CF348 Pilgrims 此题同UOJ#11 ydc的大树 Online Judge:Bzoj-4342,Codeforces-348E,Luogu-CF348E,Uoj-#11 L ...

  5. Codeforces 468D Tree

    题目 给出一棵带边权的树,求一个排列\(p\),使得\(\sum_{i=1}^{n}{dis(i, p_i)}\)的值最大,其中\(dis(v, u)\)表示\(v\)到\(u\)的距离. 算法 这题 ...

  6. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  7. uoj #9. 【UTR #1】vfk的数据 水题

    #9. [UTR #1]vfk的数据 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/9 Description ...

  8. UOJ #278. 【UTR #2】题目排列顺序(排序水题)

    #278. [UTR #2]题目排列顺序 丢个传送门:http://uoj.ac/problem/278 描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 U ...

  9. 【UTR #2】[UOJ#278]题目排列顺序 [UOJ#279]题目交流通道 [UOJ#280]题目难度提升

    [UOJ#278][UTR #2]题目排列顺序 试题描述 “又要出题了.” 宇宙出题中心主任 —— 吉米多出题斯基,坐在办公桌前策划即将到来的 UOI. 这场比赛有 n 道题,吉米多出题斯基需要决定这 ...

随机推荐

  1. Python科学计算(一)

    作者 J.R. Johansson (robert@riken.jp) http://dml.riken.jp/~rob/ 最新版本的 IPython notebook 课程文件 http://git ...

  2. 201421123042 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  3. 职场选择之大公司 VS 小公司

    其实这是个非常难回答的问题,很多职场新人都会有类似的顾虑和疑问. 这个问题就好比业界比较容易引起争议的编程语言哪个是最好的一样.大公司还是小公司里面发展,只有身处其中才能体会,如人饮水,冷暖自知. 笔 ...

  4. redis命令详解

      redis中添加key value元素:set key value;       获取元素:get key ;   redis中添加集合:lpush key value1 value2 value ...

  5. 分布式服务框架HSF

    最近在读阿里巴巴中台战略思想与架构这本书,so和大家分享一些我get到的东东. HSF是阿里巴巴内部的分布式服务框架,这个大家都很熟悉了,先上一张HSF的工作原理图: 这个图说明了HSF框架中每个组件 ...

  6. bootstrap 一个简单的登陆页面

    效果如图:用bootstrap 写的一个简单的登陆 一.修改样式 样式可以自己调整,例如换个背景色之类的,修改 background-color属性就可以 #from { background-col ...

  7. mysql(1)—— 详解一条sql语句的执行过程

    SQL是一套标准,全称结构化查询语言,是用来完成和数据库之间的通信的编程语言,SQL语言是脚本语言,直接运行在数据库上.同时,SQL语句与数据在数据库上的存储方式无关,只是不同的数据库对于同一条SQL ...

  8. spring2——IOC之Bean的装配

    spring容器对于bean的装配提供了两个接口容器分别是"ApplicationContext接口容器"和"BeanFactory接口容器",其中" ...

  9. PHP / Laravel 月刊 #23

    最新资讯 Laravel 5.6 中文文档翻译完成,译者 60 人,耗时 10 天 Summer Dingo API 中文文档翻译召集[已完成] Summer 我最喜欢 Laravel 5.6 的三个 ...

  10. Eclipse中JavaSwing图形插件安装

    1.在百度中搜索WindowBuilder,找到http://www.eclipse.org/windowbuilder/ 2.点击Download调转到页面: 因为我的eclipse版本是 3.点击 ...