我们将A省简化为由N个城市组成,某些城市之间存在双向道路,而且A省的交通有一个特点就是任意两个城市之间都能通过道路相互到达,且在不重复经过城市的情况下任意两个城市之间的到达方案都是唯一的。聪明的你一定已经发现,这些城市构成了树这样一个结构。 

现在百度陆续开了许许多多的子公司。每家子公司又会在各城市中不断兴建属于该子公司的办公室。 

由于各个子公司之间经常有资源的流动,所以公司员工常常想知道,两家子公司间的最小距离。
我们可以把子公司看成一个由办公室组成的集合。那么两个子公司A和B的最小距离定义为min(dist(x,y))(x∈A,y∈B)。其中dist(x,y)表示两个办公室之间的最短路径长度。 

现在共有Q个询问,每次询问分别在两个子公司间的最小距离。 

Input第一行一个正整数T,表示数据组数。 

对于每组数据: 

第一行两个正整数N和M。城市编号为1至N,子公司编号为1至M。 

接下来N-1行给定所有道路的两端城市编号和道路长度。 

接下来M行,依次按编号顺序给出各子公司办公室所在位置,每行第一个整数G,表示办公室数,接下来G个数为办公室所在位置。 

接下来一个整数Q,表示询问数。 

接下来Q行,每行两个正整数a,b(a不等于b),表示询问的两个子公司。 

【数据范围】 

0<=边权<=100 

1<=N,M,Q,工厂总数<=100000Output对于每个询问,输出一行,表示答案。Sample Input

1
3 3
1 2 1
2 3 1
2 1 1
2 2 3
2 1 3
3
1 2
2 3
1 3

Sample Output

1
0
0

题解:这是一道求最近公共祖先的题;我们可以随意选取一个为树根;然后可以利用邻接表将父亲和孩子联系在一起;

然后用DFS搜索记录每一节的权值和其深度;然后输入两个数,先将其深度提到相同,判断是否相等,如果不等,则继续提取

直到相同(这里用a=father[a]);

AC代码为:

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<vector>  
#include<algorithm>
using namespace std;
const int INF = 0x3fff3fff;
const int MAXN = 100010;
struct node {
int to, wt, next;
} tree[MAXN * 2];

int head[MAXN], cnt;
int n, m, q;
vector<int> office[MAXN];

void add(int from, int to, int wt) {
tree[cnt].to = to;
tree[cnt].wt = wt;
tree[cnt].next = head[from];
head[from] = cnt++;
}

void init() {
memset(head, -1, sizeof(head));
cnt = 0;
for (int i = 0; i < MAXN; ++i)office[i].clear();
}

int deep[MAXN], f[MAXN], len2f[MAXN];

void dfsDep(int root, int par, int d) {
deep[root] = d;
f[root] = par;
for (int i = head[root], to = -1; i != -1; i = tree[i].next) {
to = tree[i].to;
if (to != par) {
len2f[to] = tree[i].wt;
dfsDep(to, root, d + 1);
}
}
}

int getDis(int a, int b) {
int res = 0;
while (deep[a] < deep[b]) {
res += len2f[b];
b = f[b];
}
while (deep[a] > deep[b]) {
res += len2f[a];
a = f[a];
}
while (a != b) {
res += len2f[a] + len2f[b];
a = f[a];
b = f[b];
}
return res;
}

int main() {

int t, a, b, c;
scanf("%d", &t);
while (t--) {
init();
scanf("%d%d", &n, &m);
for (int i = 1; i < n; ++i) {
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
add(b, a, c);
}
for (int i = 1; i <= m; ++i) {
scanf("%d", &a);
for (int k = 0; k < a; ++k) {
scanf("%d", &b);
office[i].push_back(b);
}
}

dfsDep(1, -1, 0);

scanf("%d", &q);
for (int i = 1; i <= q; ++i) {
scanf("%d%d", &a, &b);
c = INF;
for (int j = 0, asz = office[a].size(); j < asz; ++j) {
for (int k = 0, bsz = office[b].size(); k < bsz; ++k) {
c = min(c, getDis(office[a][j], office[b][k]));
if (c == 0) { j = asz; break; }
}
}
printf("%d\n", c);
}
}
return 0;
}

HDU-6115的更多相关文章

  1. HDU 6115 Factory LCA,暴力

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6115 题意:中文题面 分析:直接维护LCA,然后暴力枚举集合维护答案即可. #include < ...

  2. hdu 6115(LCA 暴力)

    Factory Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total ...

  3. LCA(Lowest Common Ancesor)

    LCA(Lowest Common Ancesor) 1.基于二分搜索算法 预处理father[v][k]表示v的2的k次方层祖先,时间复杂度是O(nlogn),每次查询的时间复杂度是O(logn), ...

  4. LCA(最近公共祖先)专题(不定期更新)

    Tarjan(离线)算法 思路: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5 ...

  5. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  7. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  8. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  10. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

随机推荐

  1. 详细讲解 Redis 的两种安装部署方式

    Redis 是一款比较常用的 NoSQL 数据库,我们通常使用 Redis 来做缓存,这是一篇关于 Redis 安装的文章,所以不会涉及到 Redis 的高级特性和使用场景,Redis 能够兼容绝大部 ...

  2. 花了几个小时总结了一些容易出错的 Java 知识点!

    本文已经收录自 JavaGuide (61k+Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.欢迎 Star!欢迎骚扰!) 原文地址:https://javag ...

  3. Python基础之JSON

    作用 对Python对象进行序列化,便于存储和传输 Python对象与JSON字符串相互转换 Python对象转JSON字符串 import json data = [ { 'a' : 1, 'b' ...

  4. linux服务器MySQL数据从磁盘拷贝以及恢复

    偶有感触:遇到这个问题,经过一个下午的排查, 终于解决. 故事情节:我的阿里云服务器突然被黑客攻击了,整个系统down了. 找客服,他们排查说usr目录的文件全部丢失.让我重新初始化系统盘.初始化之前 ...

  5. 2018年航空概论课后作业(PS:部分答案不正确, 综合得分:83.6)

    1 [单选题]航空是指载人或不载人的飞行器在地球____的航行活动. • A.高空• B.大气层内• C.宇宙• D.大气层外我的答案:B 得分: 33.3分 2 [多选题]军用飞机可分为____两大 ...

  6. pat 1136 A Delayed Palindrome(20 分)

    1136 A Delayed Palindrome(20 分) Consider a positive integer N written in standard notation with k+1 ...

  7. nyoj 83-迷宫寻宝(二) (计算几何, 叉积)

    83-迷宫寻宝(二) 内存限制:10MB 时间限制:1000ms 特判: No 通过数:2 提交数:6 难度:5 题目描述: 一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个 ...

  8. Tarjan-割点

    割点——tarjan #include <bits/stdc++.h> using namespace std; ; ; int n, m; int ans;//个数 * MAXM], n ...

  9. python3 之 面向对象(类)、继承、派生和多态

    类提供了一种 组合数据和功能 的方法.创建一个新类意味着:创建一个新 类型  的对象,从而允许创建一个该类型的新 实例. 每个类的实例可以拥有: 保存自己状态的属性. 一个类的实例也可以有改变自己状态 ...

  10. es6 filter方法应用

    let arr =[ {title:'aaaa',read:100,hot:true}, {title:'bbbb',read:50,hot:false}, {title:'ccc',read:100 ...