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 ... 
随机推荐
- keeplived离线安装openssl-devel依赖包
			转载自素文宅博客:https://blog.yoodb.com/yoodb/article/detail/1434 由于公司业务并发比较高需要高可用使用LVS keeplived.在linux系统ce ... 
- spark-Worker内部工作流程
- Arduino 处理JSON格式的数据
			Arduino 处理JSON格式的数据 1.安装 ArduinoJson这个包 2.程序代码 # include <ArduinoJson.h> #define ALINK_BODY_FO ... 
- 领扣(LeetCode)两个数组的交集II 个人题解
			给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2] 示例 2: 输入: nums1 = [4,9,5 ... 
- Hadoop2.8.2 运行wordcount
			1 例子jar位置 [hadoop@hadoop02 mapreduce]$ pwd /hadoop/hadoop-2.8.2/share/hadoop/mapreduce [hadoop@hadoo ... 
- RevitAPI 隐藏UI读取Revit文件
			1.1. 新建一个控制台项目 1.2. 添加Revit API引用 我们找到revit安装目录下的这两个DLL添加到项目引用中 RevitNET.dll RevitAPI.dll 修改属性:复制本地: ... 
- PHP 的面向对象 与 类
			面向对象 == OO 学习面向对象 == XXOO;[学习使我快乐!] <!--附一个demo类的实例化--> http://note.youdao.com/noteshare?id=38 ... 
- 使用Java窗口程序执行输入的任何cmd命令
			利用Java窗口程序来执行用输入的任何命令 实现效果: Java桌面窗口,输入框.按钮,当输入框被输入命令的时候,点击按钮执行命令! 实现代码 package com.remote.remote.ag ... 
- windows 10 上使用pybind11进行C++和Python代码相互调用 | Interfacing C++ and Python with pybind11 on windows 10
			本文首发于个人博客https://kezunlin.me/post/8b9c051d/,欢迎阅读! Interfacing C++ and Python with pybind11 on window ... 
- PostGIS 使用Mysql_fdw同步ArcGIS填坑记录
			##实现Mysql_fdw数据同步过程中,出现过很多坑,开此贴记录一下 1.触发器记录 这里insert的时候,采用过insert into f_pressureline select new.*,出 ... 
