HDU-6115
现在百度陆续开了许许多多的子公司。每家子公司又会在各城市中不断兴建属于该子公司的办公室。
由于各个子公司之间经常有资源的流动,所以公司员工常常想知道,两家子公司间的最小距离。
我们可以把子公司看成一个由办公室组成的集合。那么两个子公司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的更多相关文章
- HDU 6115 Factory LCA,暴力
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6115 题意:中文题面 分析:直接维护LCA,然后暴力枚举集合维护答案即可. #include < ...
- hdu 6115(LCA 暴力)
Factory Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total ...
- LCA(Lowest Common Ancesor)
LCA(Lowest Common Ancesor) 1.基于二分搜索算法 预处理father[v][k]表示v的2的k次方层祖先,时间复杂度是O(nlogn),每次查询的时间复杂度是O(logn), ...
- LCA(最近公共祖先)专题(不定期更新)
Tarjan(离线)算法 思路: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5 ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
随机推荐
- 关于jQuery easyUI 添加合计统计行
首先在onLoadSuccess中添加计算函数:计算方法按各自业务需要,我做了一个判断非数 然后再在gatagrid表格添加行,$('#div').datagrid('appendRow', {... ...
- 产品分析:华为短信APP体验的问题和建议
- 在linux (centos)上使用puppeteer实现网页截图
1.安装nodejs和npm # 下载解压 wget -c https://nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz tar -xvf n ...
- nyoj 50-爱摘苹果的小明 (比较)
50-爱摘苹果的小明 内存限制:64MB 时间限制:1000ms Special Judge: No accepted:10 submit:15 题目描述: 小明家的院子里有一棵苹果树,每到秋天树上就 ...
- mongodb存储二进制数据
mongodb 3.x存储二进制数据并不是以base64的方式,虽然在mongo客户端的查询结果以base64方式显示,请放心使用.下面来分析存储文件的存储内容.base64编码数据会增长1/3成为顾 ...
- sql注入基本原理
SQL注入基本原理 WEB技术发展日新月异,但是徒手拼SQL的传统手艺还是受相当多的开发者亲睐.毕竟相比于再去学习一套复杂的ORM规则,手拼更说方便,直观.通常自己拼SQL的人,应该是有听说过SQL注 ...
- python进程概要
进程 狭义:正在运行的程序实例. 广义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,他是操作系统动态执行的基本单元. python的进程都是并行的. 并行:两个进程同时执行一起走. ...
- PHP中echo与print语句的实例教程
在 PHP 中,有两种基本的输出方法:echo 和 print. echo与print的差异 echo能够输出一个以上的字符串. print只能输出一个字符串,并始终返回 1. 提示:echo 比 p ...
- linux runlevel运行级别
1.linux通过设定runlevel来设定系统使用不同的服务启动,从而使得linux运行的环境有所不同. 2.当系统启动后会按照以下步骤完成初始化:运行/sbin/init程序加载器配置文件/etc ...
- css优先级之important
css优先级之important