题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547

思路:这题的本质还是LCA问题,但是需要注意的地方有:

1、如果Q中u,v的lca为u,那么只需一步u->...->v。

2、如果Q中u,v的lca为v,那么需abs(dist[u]  - dist[v])步。

3、否则以上情况都不满足,那么需abs(dist[v] - dist[lca(u, v)])+1步。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
using namespace std; const int MAX_N = (400000 + 20000);
struct Edge {
int v, next;
} edge[MAX_N]; int NE, cnt, head[MAX_N], Indegree[MAX_N];
map<string, int > mp;
void Init()
{
mp.clear();
cnt = NE = 0;
memset(head, -1, sizeof(head));
memset(Indegree, 0, sizeof(Indegree));
} void Insert(int u, int v)
{
edge[NE].v = v;
edge[NE].next = head[u];
head[u] = NE++;
} struct q_edge {
int u, v, id, next;
} q_ee[MAX_N]; int q_ne, q_head[MAX_N];
void q_init()
{
q_ne = 0;
memset(q_head, -1, sizeof(q_head));
} void q_insert(int u, int v, int id)
{
q_ee[q_ne].u = u;
q_ee[q_ne].v = v;
q_ee[q_ne].id = id;
q_ee[q_ne].next = q_head[u];
q_head[u] = q_ne++;
} int N, M, ans[MAX_N], dist[MAX_N];
int parent[MAX_N], lca[MAX_N];
bool vis[MAX_N]; int Find(int x)
{
if (x == parent[x]) {
return parent[x];
}
return parent[x] = Find(parent[x]);
} void dfs(int u)
{
parent[u] = u;
vis[u] = true;
for (int i = q_head[u]; ~i; i = q_ee[i].next) {
int v = q_ee[i].v, id = q_ee[i].id;
if (vis[v]) { lca[id] = Find(v);
}
} for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if (!vis[v]) {
dist[v] = dist[u] + 1;
dfs(v);
parent[v] = u;
}
}
} int main()
{
int Cas;
cin >> Cas;
while (Cas--) {
cin >> N >> M; Init(); for (int i = 1; i < N; ++i) {
string str1, str2;
cin >> str1 >> str2;
if (mp.find(str1) == mp.end()) mp[str1] = ++cnt;
if (mp.find(str2) == mp.end()) mp[str2] = ++cnt; Indegree[mp[str1]]++;
Insert(mp[str2], mp[str1]);
} q_init(); for (int i = 1; i <= M; ++i) {
string str1, str2;
cin >> str1 >> str2;
q_insert(mp[str1], mp[str2], i);
q_insert(mp[str2], mp[str1], i);
} //from root;
memset(vis, false, sizeof(vis));
for (int i = 1; i <= cnt; ++i) {
if (!Indegree[i]) {
dist[i] = 0;
dfs(i);
break;
}
} for (int i = 0; i < q_ne; ++i) {
if (!(i & 1)) {
if (q_ee[i].u == q_ee[i].v) {
puts("0");
} else if (q_ee[i].u == lca[q_ee[i].id]) {
puts("1");
} else if (q_ee[i].v == lca[q_ee[i].id]) {
printf("%d\n", abs(dist[q_ee[i].v] - dist[q_ee[i].u]));
} else {
printf("%d\n", abs(dist[q_ee[i].u] - dist[lca[q_ee[i].id]]) + 1);
}
}
} }
return 0;
}



hdu 4547(LCA)的更多相关文章

  1. 洛谷P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...

  2. 图论--最近公共祖先问题(LCA)模板

    最近公共祖先问题(LCA)是求一颗树上的某两点距离他们最近的公共祖先节点,由于树的特性,树上两点之间路径是唯一的,所以对于很多处理关于树的路径问题的时候为了得知树两点的间的路径,LCA是几乎最有效的解 ...

  3. 面试题6:二叉树最近公共节点(LCA)《leetcode236》

    Lowest Common Ancestor of a Binary Tree(二叉树的最近公共父亲节点) Given a binary tree, find the lowest common an ...

  4. P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  5. A * B Problem Plus HDU - 1402 (FFT)

    A * B Problem Plus HDU - 1402 (FFT) Calculate A * B.  InputEach line will contain two integers A and ...

  6. 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  7. 「LuoguP3379」 【模板】最近公共祖先(LCA)

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  8. 洛谷——P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  9. luogo p3379 【模板】最近公共祖先(LCA)

    [模板]最近公共祖先(LCA) 题意 给一个树,然后多次询问(a,b)的LCA 模板(主要参考一些大佬的模板) #include<bits/stdc++.h> //自己的2点:树的邻接链表 ...

随机推荐

  1. python 下 tinker、matplotlib 混合编程示例一个

    该例是实现了 Tinker 嵌入 matplotlib 所绘制的蜡烛图(k 线),数据是从 csv 读入的.花一下午做的,还很粗糙,仅供参考.python 代码如下: import matplotli ...

  2. java List 和Map的使用

    一.MAP package net.xsoftlab.baike; import java.util.HashMap;import java.util.Iterator;import java.uti ...

  3. 11月8日PHP练习《留言板》

    一.要求 二.示例页面 三.网页代码及网页显示 1.denglu.php  登录页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...

  4. 面试题目——《CC150》数学与概率

    面试题7.2:三角形的三个顶点上各有一只蚂蚁.如果蚂蚁开始沿着三角形的边爬行,两只或三只蚂蚁撞到一起的概率有多大?假定每只蚂蚁会随机选一个方向,每个方向被选到的几率相等,而且三只蚂蚁的爬行速度相同. ...

  5. lucene大索引文件分布式存储方案

    这几天实现了个Lucene分布式检索的模块,采用的分布式方案是将数据分块,分别生成N个索引文件,放到N个节点上运行.检索时,对每一个节点发出查询请求,将N个节点返回的结果归并,然后生成一个新的结果.如 ...

  6. tamtam-nuget-imageserver

    https://bitbucket.org/tamtam-nl/tamtam-nuget-imageserver/src/eaddb1ac943fcaa9e7ef210ed5a5ccf630b8699 ...

  7. 线程安全的无锁RingBuffer的实现

    这里的线程安全,是指一个读线程和一个写线程,读写两个线程是安全的,而不是说多个读线程和多个写线程是安全的.. 在程序设计中,我们有时会遇到这样的情况,一个线程将数据写到一个buffer中,另外一个线程 ...

  8. MySql 里的IFNULL、NULLIF和ISNULL用法区别

    mysql中isnull,ifnull,nullif的用法如下: isnull(expr) 的用法:如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0. mysql> ...

  9. PHP session

    PHP Session PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置.Session 变量存储单一用户的信息,并且对于应用程序中的 ...

  10. ASCII码表

    ASCII码表 ASCII码大致可以分作三部分組成. 第一部分是:ASCII码非打印控制字符: 第二部分是:ASCII码打印字符: 第三部分是:扩展ASCII码打印字符. 第一部分:ASCII非打印控 ...