题目链接: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. php判断中文,英文, 数字

    exeg Warning  This function was DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0. function checkStr ...

  2. mysql免安装使用(win7 64位系统)

    一.解压 二.以管理员身份运行cmd 三.cmd命令进入到解压后的mysql文件bin目录下 四.将mysql服务添加到windows服务中.cmd在bin目录下输入:mysqld -install  ...

  3. linux中ls命令

    ls跟dos下的dir命令是一样的都是用来列出目录下的文件 ls参数: -a: ls -a 列出文件下所有的文件,包括以"."开头的隐藏文件(linux下文件隐藏文件是以.开头的, ...

  4. 关于学习JavaScript 的 高三编程 一些心得(三)

    最近在学习高三的 过程中,遇到的了一些 难以理解的问题, 在看到第五章之前都是 OK 的.但是到了 引用类型的时候就有点蒙了. 首先我们看下,引用类型的  解释:[引用类型的值(对象)是引用类型的一个 ...

  5. multipart/form-data和application/x-www-form-urlencoded的区别

    在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型. 下边是说明:  application/x-www-form-urle ...

  6. PF_INET 和 AF_INET 的区别

    在写网络程序的时候,建立TCP socket: sock = socket(PF_INET, SOCK_STREAM, 0); 然后再绑定本地地址或连接远程地址时需要初始化sockaddr_in结构, ...

  7. 第3月第8天 RefCounted PlistBuddy

    1.RefCounted引用计数 class Frame : public RefCounted<Frame> { // ... } http://www.cnblogs.com/dsky ...

  8. ReactiveCocoa源码拆分解析(六)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) RAC为了实现优雅的信号绑定,可谓使尽浑身解数,不仅 ...

  9. (转载)robots.txt写法大全和robots.txt语法的作用

    1如果允许所有搜索引擎访问网站的所有部分的话 我们可以建立一个空白的文本文档,命名为robots.txt放在网站的根目录下即可.robots.txt写法如下:User-agent: *Disallow ...

  10. MySQL 5.5编译安装

    MYSQL数据库安装方法 yum/rpm方式安装mysql 只要执行yum install mysql-server即可. yum/rpm方式安装mysql应用场景:yum/rpm安装适用对数据库要求 ...