题目链接:https://www.nowcoder.com/acm/contest/15/C

思路:虚树,取两点间的lca,构造成一颗新的树;求(直径+1)/2即可

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<bitset>
#include<time.h>
using namespace std;
#define LL long long
#define pi (4*atan(1.0))
#define eps 1e-8
#define bug(x) cout<<"bug"<<x<<endl;
const int N=3e5+,M=1e6+,inf=1e9+,MOD=1e9+;
const LL INF=1e18+,mod=1e9+; struct edge
{
int v,next;
}edge[N<<];
int head[N],fa[N][],edg,deep[N];
int in[N],out[N],tot;
void init()
{
memset(head,-,sizeof(head));
edg=;tot=;
}
void add(int u,int v)
{
edg++;
edge[edg].v=v;
edge[edg].next=head[u];
head[u]=edg;
}
void dfs(int u,int fat)
{
tot++;
in[u]=tot;
for (int i=; i<= ;i++)
fa[u][i] = fa[fa[u][i-]][i-];
for (int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if(v==fat) continue;
deep[v]=deep[u]+;
fa[v][]=u;
dfs(v,u);
}
out[u]=tot;
}
int RMQ_LCA(int x,int y) {
if(deep[x]<deep[y]) swap(x,y);
int d=deep[x]-deep[y];
for (int i=; i<= ;i++)
if((<<i)&d) x=fa[x][i];
for (int i=; i>= ;i--) {
if(fa[x][i]!=fa[y][i]) {
x=fa[x][i];y=fa[y][i];
}
}
if(x==y) return x;
else return fa[x][];
} int h[M],ans,far,pos;
struct f
{
int v,w,nex;
}edge2[N<<];
int head2[N],edg2;
void add2(int u,int v,int w)
{
edge2[++edg2]=(f){v,w,head2[u]};
head2[u]=edg2;
}
bool cmp(int u, int v) {
return in[u] < in[v];
}
bool check(int u, int v) {
return in[u] <= in[v] && in[v] <= out[u];
}
int build(int A[], int tot) {
std::sort(A + , A + + tot, cmp);
for(int i = , old_tot = tot; i <= old_tot; i++) {
A[++tot] = RMQ_LCA(A[i - ], A[i]);
}
std::sort(A + , A + + tot, cmp);
tot = std::unique(A + , A + + tot) - A - ; std::stack<int> S; S.push(A[]);
for(int i = ; i <= tot; i++) {
while(!S.empty() && !check(S.top(), A[i])) S.pop();
int u = S.top(), v = A[i];
add2(u,v,deep[v]-deep[u]);
add2(v,u,deep[v]-deep[u]);//u, v, deep[v] - deep[u]);
S.push(v);
}
return tot;
}
void dfs1(int u,int fa,int val)
{
if(val>far)far=val,pos=u;
for(int i=head2[u];i!=-;i=edge2[i].nex)
{
int v=edge2[i].v;
int w=edge2[i].w;
if(v==fa)continue;
dfs1(v,u,val+w);
}
}
void dfs2(int u,int fa,int val)
{
ans=max(ans,val);
for(int i=head2[u];i!=-;i=edge2[i].nex)
{
int v=edge2[i].v;
int w=edge2[i].w;
if(v==fa)continue;
dfs2(v,u,w+val);
}
}
int main()
{
init();
memset(head2,-,sizeof(head2));
int n;
scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(,);
int q;
scanf("%d",&q);
while(q--)
{
edg2=far=pos=ans=;
int t;
scanf("%d",&t);
for(int i=;i<=t;i++)
scanf("%d",&h[i]);
t = build(h, t);
dfs1(h[],,);
dfs2(pos,,);
printf("%d\n",(ans+)/);
for(int i=;i<=t;i++)
head2[h[i]]=-;
}
return ;
}

Wannafly挑战赛1 C MMSet2 虚树的更多相关文章

  1. Wannafly挑战赛18 E 极差(线段树、单调栈)

    Wannafly挑战赛18 E 极差 题意 给出三个长度为n的正整数序列,一个区间[L,R]的价值定义为:三个序列中,这个区间的极差(最大值与最小值之差)的乘积. 求所有区间的价值之和.答案对\(2^ ...

  2. Wannafly挑战赛2_D Delete(拓扑序+最短路+线段树)

    Wannafly挑战赛2_D Delete Problem : 给定一张n个点,m条边的带权有向无环图,同时给定起点S和终点T,一共有q个询问,每次询问删掉某个点和所有与它相连的边之后S到T的最短路, ...

  3. 【Wannafly挑战赛29F】最后之作(Trie树,动态规划,斜率优化)

    [Wannafly挑战赛29F]最后之作(Trie树,动态规划,斜率优化) 题面 牛客 题解 首先考虑怎么计算\([l,r]\)这个子串的不同的串的个数. 如果\(l=1\),我们构建\(Trie\) ...

  4. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  5. 良心送分题(牛客挑战赛35E+虚树+最短路)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 给你一棵树,然后把这棵树复制\(k\)次,然后再添加\(m\)条边,然后给你起点和终点,问你起点到终点的最短路. 思路 由于将树复制\(k\) ...

  6. HDU-6035:Colorful Tree(虚树+DP)

    这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...

  7. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  8. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  9. Wannafly挑战赛22游记

    Wannafly挑战赛22游记 幸运的人都是相似的,不幸的人各有各的不幸. --题记 A-计数器 题目大意: 有一个计数器,计数器的初始值为\(0\),每次操作你可以把计数器的值加上\(a_1,a_2 ...

随机推荐

  1. centos7.5 安装gaussian09和 gaussianview4

    一.安装gaussian09 1. 解压安装包 $ mkdir Gaussian$ cd Gaussian$ tar xvf g09_linux.tar 2. 设置环境变量 #gaussian09 e ...

  2. iOS 开发笔记 - 导航到地图

    导航到地图,已经不是什么新鲜事了.网上有好多参考的资料,我总结出只需要两步 第一步:在info中加上支持的各平台 比如:iosamap高德地图.comgooglemaps谷歌地图.baidumap百度 ...

  3. js优化 前端小白适用

    注意啦,前端初学者适合看的js优化,当你看我的优化认为太low,那么恭喜,你已经脱离初学者了. 首先这边我觉得分享的还是以js为主,前端性能优化,我认为最重要的还是js,因为js是一门解释型的语言,相 ...

  4. 常见的四种文本自动分词详解及IK Analyze的代码实现

    以下解释来源于网络-百度百科 1.word分词器 word分词 [1]  是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义.能准确识别英文.数字, ...

  5. SQL 一列数据整合为一条数据

    SQL 一列数据整合为一条数据: SELECT  STUFF(( SELECT distinct  ',' + 列名 FROM 表名 where  [条件] FOR XML PATH('') ), 1 ...

  6. Mysql 导入文件提示 --secure-file-priv option 问题

    MYSQL导入数据出现:The MySQL server is running with the --secure-file-priv option so it cannot execute this ...

  7. 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165215

    2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 20165215 目录 Kali的下载及安装 网络配置 设置共享文件夹及剪切板 更新软件源 [Kali的下载及安 ...

  8. 融云携新版实时音视频亮相 LiveVideoStack 2019

    4 月 19 日,LiveVideoStack 2019 音视频大会在上海隆重开幕,全球多媒体创新专家.音视频技术工程师.产品负责人.高端行业用户等共襄盛会,聚焦音频.视频.图像.AI 等技术的最新探 ...

  9. 打开visual studio 2010报错:未能正确加载“VSTS for Database Professionals Sql Server Data-tier Application”包

    1  解决: 运行cmd 2  输入:regsvr32 %windir%\system32\jscript.dll

  10. java eclipse war包的二次开发方法

    有实际项目在跑的war包,却没有源码,苦于想查看源码,身处运维组为研发组看不起,拿不到源码,只能自己来反编译了. 只要你细心点,其实在解压war包后,可以看到文件夹中,已经存在了jsp文件,但是却没有 ...