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 时间限制: ...
随机推荐
- VJhrbustacm0304专题一题解
L:搬果子 用一般的priority_queue做就可以了. 优先队列//扔进去就能自动排序的序列,记得T组数据要pop干净 #include<iostream> #include< ...
- CodeForces - 922D Robot Vacuum Cleaner (贪心)
Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that Pushok is a ...
- 【2016常州一中夏令营Day3】
小 W 摆石子[问题描述]小 W 得到了一堆石子,要放在 N 条水平线与 M 条竖直线构成的网格的交点上.因为小 M 最喜欢矩形了,小 W 希望知道用 K 个石子最多能找到多少四边平行于坐标轴的长方形 ...
- tensorflow学习笔记——ResNet
自2012年AlexNet提出以来,图像分类.目标检测等一系列领域都被卷积神经网络CNN统治着.接下来的时间里,人们不断设计新的深度学习网络模型来获得更好的训练效果.一般而言,许多网络结构的改进(例如 ...
- 牛客多校第一场 B Inergratiion
牛客多校第一场 B Inergratiion 传送门:https://ac.nowcoder.com/acm/contest/881/B 题意: 给你一个 [求值为多少 题解: 根据线代的知识 我们可 ...
- 安卓APP动态调试(IDA实用攻略)
转自:http://drops.wooyun.org/mobile/5942 0x00 前言 随着智能手机的普及,移动APP已经贯穿到人们生活的各个领域.越来越多的人甚至已经对这些APP应用产生了依赖 ...
- 博客同步到CSDN客户端
同步本人博客到CSDN客户端 http://blog.csdn.net/johnnyz1234
- 五分钟学Java:可变参数究竟是怎么一回事?
在逛 programcreek 的时候,我发现了一些专注基础但不容忽视的主题.比如说:Java 的可变参数究竟是怎么一回事?像这类灵魂拷问的主题,非常值得深入地研究一下. 我以前很不重视基础,觉得不就 ...
- Linux 学习笔记 4 创建、复制、移动、文件的基本操作
写在前面 通过上一节的学习,我们基本的了解到在Linux 里面对于设备的挂载.卸载以及设备存在的目录.挂载目录.都有了一个基本的了解 本节主要了解文件.以及目录的相关操作,比如文件.目录的创建.以及删 ...
- node多进程的创建与守护
node是单线程运行,我们的node项目如何利用多核CPU的资源,同时提高node服务的稳定性呢? 1. node的单线程 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系 ...