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 时间限制: ...
随机推荐
- CF1208
CF1208 打的话貌似能够涨分的样子? A 水题 B 枚举左端点,看看右端点的最近位置 开一个类似于桶的东西维护一下上一次出现位置 左端点左边就删掉,否则就要将上一次出现的位置删掉 时间复杂度\(O ...
- LuoguP5464 缩小社交圈
LuoguP5464 缩小社交圈 背景:洛谷七月月赛T4 题目大意给定\(n\)个点,每个点的权值对应着一个区间\([l_i,r_i]\),两个点\(i,j\)有边当且仅当他们权值的并集不为空集,问有 ...
- HDU 6662 Acesrc and Travel (换根dp)
Problem Description Acesrc is a famous tourist at Nanjing University second to none. During this sum ...
- 两种常见的缓存淘汰算法LFU&LRU
1. LFU 1.1. 原理 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”. 1.2. ...
- Jmeter配置元件——CSV DataSet Config参数化
在聊CSV DataSet Config配置元件前,先来讨论下为何要参数化? 比如在做性能测试过程中, 一般我们需要模拟多个用户进行操作, 为了满足实际场景, 模拟真实的用户行为, 我们需要做到模拟的 ...
- JDBC 数据源
概述 JNDI 数据源配置的相关内容已经在 JNDI 资源文档中详细介绍过.但从 Tomcat 用户的反馈意见来看,有些配置的细节问题非常棘手. 针对常用的数据库,我们已经给 Tomcat 用户提供了 ...
- linux中的文件类型标记方法
在ls -l显示的详细信息中有以下信息: -rw-r--r-- drwxr-xr-x 一共10个字符,第一个字符表示文件类型,后面9个字符分成3组表示文件权限.前三个表示属主(拥有者)对文件的权限,中 ...
- docker(整理中
docker镜像默认的下载地址就是docker的官网,而他们的官网在国内没有节点,时不时就被国家防火墙隔绝,会出现DNS解析不到,或者找不到镜像等狗血提示. 解决的方法有三个: 第一,就是不断尝试,因 ...
- 49.植入HTML和自定义元件库
首先设置一个圆角矩形 设置鼠标单击时的k空用例 这样当鼠标单击时会有一个小手的图标 然后设置鼠标移入时的动作 鼠标移入时设置文本动作的文本
- 【Composer】PHP开发者必须了解!
Composer是一个非常流行的PHP包依赖管理工具,已经取代PEAR包管理器,对于PHP开发者来说掌握Composer是必须的. 对于使用者来说Composer非常的简单,通过简单的一条命令将需要的 ...