搬家一个月,庆祝一下

啪啪啪啪啪啪啪啪啪啪❀❀❀❀

题目传送门

分析:

这什么奇奇怪怪的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"的更多相关文章

  1. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  2. hihoCoder 1427 : What a Simple Research(大㵘研究)

    hihoCoder #1427 : What a Simple Research(大㵘研究) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 ...

  3. hihoCoder 1385 : A Simple Job(简单工作)

    hihoCoder #1385 : A Simple Job(简单工作) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 Institute ...

  4. 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 ...

  5. hihocoder 1829 - 压缩字符串 - [状压+暴力枚举][2018ICPC北京网络预赛B题]

    题目链接:https://hihocoder.com/problemset/problem/1829 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Lara Croft, ...

  6. hihoCoder 1128 二分查找

    Description Input and Output Codes 描述#1128 : 二分·二分查找 Description Nettle最近在玩<艦これ>,因此Nettle收集了很多 ...

  7. hihocoder -1121-二分图的判定

    hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...

  8. Hihocoder 太阁最新面经算法竞赛18

    Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...

  9. hihoCoder太阁最新面经算法竞赛15

    hihoCoder太阁最新面经算法竞赛15 Link: http://hihocoder.com/contest/hihointerview24 题目1 : Boarding Passes 时间限制: ...

随机推荐

  1. 天使玩偶/SJY摆棋子

    P4169 [Violet]天使玩偶/SJY摆棋子 CDQ分治的题目. 我们发现题目要我们求的\(|A_x-B_x|+|A_y-B_y|\)的绝对值号比较恶心. 试想一下怎么去掉 如果所有的点都在我们 ...

  2. Sending Packets LightOJ - 1321 (期望计算)

    题面: Alice and Bob are trying to communicate through the internet. Just assume that there are N route ...

  3. C#调用smtp邮件发送几个大坑

    1.网易.新浪邮箱新增了一个叫“授权码”的东西,开通smtp服务时,必须开启授权码,并且邮件发送代码中也需要加上授权码,如下代码: //指定邮箱账号和密码,需要注意的是,这个密码是你在邮箱设置里开启服 ...

  4. POJ - 3177 Redundant Paths 说说连通分量吧

    ----我想说说双联通分量还有割点和桥 1.割点(一个点,如果没有这一个点,图就会变得不连通) 2.桥(一条边,断开这条边就会让图不连通) 3.点双连通(没割点的图) 4.边双连通(没桥的图) 5.割 ...

  5. 【他山之石】mysql编码问题总结

    有些问题可能比较基础,但是没有经过系统学习还是可能会出错,记录下. 这次是mysql的编码问题. 背景是部署新的测试环境,给了一台服务器还有在另一个环境下的mysql,配置过程中发现mysql编码有问 ...

  6. Pycharm学生版安装教程(2019-12月更新)

    以下方法全部是官方渠道正版激活,可选择学生版(免费) 或企业版(付费) 我的机器学习教程「美团」算法工程师带你入门机器学习  以及 「三分钟系列」数据结构与算法  已经开始更新了,欢迎大家订阅~这篇专 ...

  7. 一文详解滑动平均法、滑动平均模型法(Moving average,MA)

    任何关于算法.编程.AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI.算法.编程和大数据知识分享,以及免费的SSR节点和 ...

  8. 调试排错 - Java问题排查:Linux命令

    本文原创,更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. Java 在线问题排查主要分两篇:本文是第一篇,通过linux常用命令排查.@pdai 文本操作 文本查找 - grep g ...

  9. 在Mac/linux上查找(并终止)进程锁定特定端口的几种方法

    前言  无论是做网站还是做产品,经常使用到杀死某个进程的方法.制作脚本并熟悉运用是一个非常节省时间的方法. 基本命令  查找: [sudo] lsof -i :3000  杀戮 kill -9 方法一 ...

  10. zabbix 4.04 安装文档 - 基于CentOS 7.6

    1    安装前准备: 1.1   安装JDK 卸载openjdk # rpm -qa | grep java # yum remove java-1.8.0-openjdk # yum remove ...