hihoCoder 1387 A Research on "The Hundred Family Surnames"
搬家一个月,庆祝一下
啪啪啪啪啪啪啪啪啪啪❀❀❀❀
题目传送门
分析:
这什么奇奇怪怪的OJ,以前从来不知道的2333
以前只知道合并两个连通块时,其中一边直径端点为A,B,另一边为C,D
D=max( dis(A,B) , dis(A,C) , dis(A,D) , dis(B,C) , dis(B,D) , dis(C,D) )
原来合并两颗就在原树上可能交叉的虚树,竟然也可以用这个
而且多条直径也不会影响答案??
细想一下貌似很有道理的亚子。。。
记录记录2333
调了半天
这个歪歪扣不仅丧病而且脑子不太好使,虚树上两点之间连边距离不是1
太菜了dbq
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<string> #define maxn 500005
#define INF 0x3f3f3f3f using namespace std; inline long long getint()
{
long long num=,flag=;char c;
while((c=getchar())<''||c>'')if(c=='-')flag=-;
while(c>=''&&c<='')num=num*+c-,c=getchar();
return num*flag;
} int n,m,N;
int fir[maxn],nxt[maxn],to[maxn],cnt;
int fa[maxn],dpt[maxn],tp[maxn],sz[maxn],son[maxn];
int In[maxn],Out[maxn],cur;
int stk[maxn],top;
int Id[maxn];
int h[maxn],f[maxn];
vector<int>H[maxn];
int Rt[maxn][];
map<string,int>M;
vector<int>G[maxn];
inline bool cmp(int x,int y){return In[x]<In[y];} inline void newnode(int u,int v)
{to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;} inline void dfs1(int u)
{
sz[u]=;
for(int i=fir[u];i;i=nxt[i])
if(to[i]!=fa[u])
{
dpt[to[i]]=dpt[u]+,fa[to[i]]=u;
dfs1(to[i]);
sz[u]+=sz[to[i]];if(sz[to[i]]>sz[son[u]])son[u]=to[i];
}
} inline void dfs2(int u,int ac)
{
In[u]=++cur,tp[u]=ac;
if(son[u])dfs2(son[u],ac);
for(int i=fir[u];i;i=nxt[i])if(to[i]!=fa[u]&&to[i]!=son[u])dfs2(to[i],to[i]);
Out[u]=cur;
} inline int LCA(int u,int v)
{
while(tp[u]!=tp[v])
{
if(dpt[tp[u]]<dpt[tp[v]])swap(u,v);
u=fa[tp[u]];
}
return dpt[u]<dpt[v]?u:v;
} inline void getdp(int u,int lst)
{
for(int i=G[u].size()-;~i;i--)if(G[u][i]!=lst)
f[G[u][i]]=f[u]+abs(dpt[u]-dpt[G[u][i]]),getdp(G[u][i],u);
} inline void solve(int x)
{
int K=H[x].size();top=;
for(int i=;i<K;i++)h[i+]=H[x][i];
sort(h+,h+K+,cmp);
for(int i=K-;i;i--)h[++K]=LCA(h[i],h[i+]);
sort(h+,h+K+,cmp);K=unique(h+,h+K+)-h-;
stk[++top]=h[];
for(int i=;i<=K;i++)
{
while(top&&Out[stk[top]]<In[h[i]])top--;
if(top)G[stk[top]].push_back(h[i]),G[h[i]].push_back(stk[top]);
stk[++top]=h[i];
}
int rt=h[];
f[rt]=;getdp(rt,rt);
for(int i=;i<=K;i++)if(f[h[i]]>f[rt])rt=h[i];
Rt[x][]=rt;
f[rt]=;getdp(rt,rt);
for(int i=;i<=K;i++)if(f[h[i]]>f[rt])rt=h[i];
Rt[x][]=rt;
for(int i=;i<=K;i++)G[h[i]].clear();
} inline int getdis(int u,int v)
{return dpt[u]+dpt[v]-*dpt[LCA(u,v)];} inline int getans(int x,int y)
{
int A=Rt[x][],B=Rt[x][],C=Rt[y][],D=Rt[y][];
return max(max(getdis(A,C),getdis(A,D)),max(getdis(B,C),getdis(B,D)));
} int main()
{
while(~scanf("%d%d",&n,&m))
{
M.clear();
memset(fir,,sizeof fir),cnt=;
memset(son,,sizeof son);cur=;
memset(fa,,sizeof fa),memset(sz,,sizeof sz);
memset(tp,,sizeof tp),memset(dpt,,sizeof dpt);
memset(Rt,,sizeof Rt);memset(Id,,sizeof Id);
memset(In,,sizeof In),memset(Out,,sizeof Out);
for(int i=;i<=n;i++)
{
string tmp;cin>>tmp;
if(!M.count(tmp))M[tmp]=++N;
Id[i]=M[tmp];
H[M[tmp]].push_back(i);
}
for(int i=;i<n;i++)
{
int u=getint(),v=getint();
newnode(u,v),newnode(v,u);
}
dfs1(),dfs2(,);
for(int i=;i<=N;i++)solve(i);
while(m--)
{
string tmp1,tmp2;
cin>>tmp1>>tmp2;
if(!M.count(tmp1)||!M.count(tmp2))printf("-1\n");
else printf("%d\n",getans(M[tmp1],M[tmp2])+);
}
for(int i=;i<=N;i++)H[i].clear();N=;
}
}

hihoCoder 1387 A Research on "The Hundred Family Surnames"的更多相关文章
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- hihoCoder 1427 : What a Simple Research(大㵘研究)
hihoCoder #1427 : What a Simple Research(大㵘研究) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 ...
- hihoCoder 1385 : A Simple Job(简单工作)
hihoCoder #1385 : A Simple Job(简单工作) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 Institute ...
- The top 100 papers Nature explores the most-cited research of all time.
The top 100 papers Nature explores the most-cited research of all time. The discovery of high-temper ...
- hihocoder 1829 - 压缩字符串 - [状压+暴力枚举][2018ICPC北京网络预赛B题]
题目链接:https://hihocoder.com/problemset/problem/1829 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, ...
- hihoCoder 1128 二分查找
Description Input and Output Codes 描述#1128 : 二分·二分查找 Description Nettle最近在玩<艦これ>,因此Nettle收集了很多 ...
- hihocoder -1121-二分图的判定
hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...
- Hihocoder 太阁最新面经算法竞赛18
Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...
- hihoCoder太阁最新面经算法竞赛15
hihoCoder太阁最新面经算法竞赛15 Link: http://hihocoder.com/contest/hihointerview24 题目1 : Boarding Passes 时间限制: ...
随机推荐
- vue-learning:5-template-v-for
5 列表渲染的指令v-for v-for on Array / Object / String / Number v-for on template v-for on expression v-for ...
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- Android生命周期函数执行顺序
转载自:http://blog.csdn.net/intheair100/article/details/39061473 程序正常启动:onCreate()->onStart()->on ...
- TDengine 时序数据库的 ADO.Net Core 提供程序 Maikebing.EntityFrameworkCore.Taos
简介 Entity, Framework, EF, Core, Data, O/RM, entity-framework-core,TDengine Maikebing.Data.Taos 是一个基于 ...
- 将 Sidecar 容器带入新的阶段
作者 | 徐迪.张晓宇 导读:本文根据徐迪和张晓宇在 KubeCon NA 2019 大会分享整理.分享将会从以下几个方面进行切入:首先会简单介绍一下什么是 Sidecar 容器:其次,会分享几个阿里 ...
- linux下安装MariaDB数据库
搜素某个文件:find / -name '文件名(或文件夹名)' 1.编辑yum源:vi /etc/yum.repos.d/MariaDB.repo 2.编辑文件时用到的vi命令: vi 打开一个不存 ...
- Windows远程桌面管理--功能强大的远程批量管理工具【转】
曾经,我想着要是有一款绿色小巧,功能实用的远程桌面管理工具,其界面简洁,操作便捷,能够同时远程操作多台服务器,并且多台服务器间可以自由切换,适用于网站管理人员使用的工具该有多好,苍天不负有心人,终于出 ...
- linux权限说明
Linux 中的权限 这里我拿一个tomcat目录举例说明.首先我们在linux系统中执行命令:ls -l 我们拿出其中一个说明-rwxr-xr-x,在Linux 系统中权限是区分用户的,即用户.组用 ...
- javascript数组大全(一张图列出数组的所有方法)
把所有数组的方法列在了一张图上,为了自己温故一下,也为了以后忘记时好查阅. 如果大家在上面查阅方法,可以找到对应的方法名,看前面简单的注释,还是不能明白的话,可以看一下官网说明,地址给大家列出来,MD ...
- 「Luogu P1435」回文字串 解题报告
题面 主要大衣大意: 给定一个字符串,求至少加入多少个字符才能使字符串变成回文字符串 下面就是我一本正经的胡说八道题解 思路: 很显然,这应该是一道典型的最长公共子序列的题目 因此,主要思想就是DP ...