ZOJ3195 Design the city [2017年6月计划 树上问题04]

Design the city


Time Limit: 1 Second      Memory Limit: 32768 KB


Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now, Cerror finds out that the main reason of them is the poor design of the roads distribution, and he want to change this situation.

In order to achieve this project, he divide the city up to N regions which can be viewed as separate points. He thinks that the best design is the one that connect all region with shortest road, and he is asking you to check some of his designs.

Now, he gives you an acyclic graph representing his road design, you need to find out the shortest path to connect some group of three regions.

Input

The input contains multiple test cases! In each case, the first line contian a interger N (1 < N < 50000), indicating the number of regions, which are indexed from 0 to N-1. In each of the following N-1 lines, there are three interger Ai, Bi, Li (1 < Li < 100) indicating there‘s a road with length Li between region Ai and region Bi. Then an interger Q (1 < Q < 70000), the number of group of regions you need to check. Then in each of the following Q lines, there are three interger Xi, Yi, Zi, indicating the indices of the three regions to be checked.

Process to the end of file.

Output

Q lines for each test case. In each line output an interger indicating the minimum length of path to connect the three regions.

Output a blank line between each test cases.

Sample Input

4
0 1 1
0 2 1
0 3 1
2
1 2 3
0 1 2
5
0 1 1
0 2 1
1 3 1
1 4 1
2
0 1 2
1 0 3

Sample Output

3
2

2
2


Author: HE, Zhuobin

Source: ZOJ Monthly, May 2009

三个点的距离等于任意两点间距离加和除以2

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
inline void read(int &x)
{
	char ch = getchar();char c = ch;x = 0;
	while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
	while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
	if(c == ‘-‘)x = -x;
}
inline void swap(int& a, int& b){int tmp = a;a = b;b = tmp;}
const int MAXN = 50000 + 10;
struct Edge{int u,v,w,next;}edge[MAXN << 1];
int head[MAXN], cnt, n, m;
inline void insert(int a,int b, int c){edge[++cnt] = Edge{a,b,c,head[a]};head[a] = cnt;}
int log2[MAXN], pow2[30];
int p[30][MAXN], deep[MAXN], len[MAXN];int b[MAXN];

void dfs(int u)
{
	for(int pos = head[u];pos;pos = edge[pos].next)
	{
		int v = edge[pos].v;
		if(b[v])continue;
		b[v] = true;
		len[v] = len[u] + edge[pos].w;
		deep[v] = deep[u] + 1;
		p[0][v] = u;
		dfs(v);
	}
}

inline void yuchuli()
{
	b[1] = true;
	deep[1] = 0;
	dfs(1);
	for(register int i = 1;i <= log2[n];i ++)
		for(register int j = 1;j <= n;j ++)
			p[i][j] = p[i - 1][p[i - 1][j]];
}

inline int lca(int va, int vb)
{
	if(deep[va] < deep[vb])swap(va,vb);
	for(register int i = log2[n];i >= 0;i --)
		if(deep[va] - pow2[i] >= deep[vb])
			va= p[i][va];
	if(va == vb)return va;
	for(register int i = log2[n];i >= 0;i --)
	{
		if(p[i][va] != p[i][vb])
		{
			va = p[i][va];
			vb = p[i][vb];
		}
	}
	return p[0][va];
}

inline int l(int va, int vb)
{
	int k = lca(va, vb);
	return len[va] + len[vb] - (len[lca(va, vb)] << 1);
}

int main()
{
	register int tmp1,tmp2,tmp3;
	log2[0] = -1;
	for(register int i = 1;i <= MAXN;++ i)log2[i] = log2[i >> 1] + 1;
	pow2[0] = 1;
	for(register int i = 1;i <= 30;++ i)pow2[i] = pow2[i - 1] << 1;
	bool ok = false;
	while(scanf("%d", &n) != EOF)
	{
		if(ok)putchar(‘\n‘),putchar(‘\n‘);
		cnt = 0;memset(head, 0, sizeof(head));
		memset(edge, 0, sizeof(edge));
		memset(deep, 0, sizeof(deep));
		memset(p, 0, sizeof(p));m = 0;
		memset(b, 0, sizeof(b));
		memset(len, 0, sizeof(len));
		for(register int i = 1;i < n;++ i)
		{
			read(tmp1);read(tmp2);read(tmp3);
			insert(tmp1 + 1, tmp2 + 1, tmp3);
			insert(tmp1 + 1, tmp1 + 1, tmp3);
		}
		yuchuli();
		read(m);
		read(tmp1);read(tmp2);read(tmp3);
		++ tmp1;++ tmp2;++ tmp3;
		printf("%d", (l(tmp1, tmp2) + l(tmp2, tmp3) + l(tmp1, tmp3))>> 1);
		for(register int i = 2;i <= m;++ i)
		{
			read(tmp1);read(tmp2);read(tmp3);
			tmp1 ++;tmp2 ++;tmp3 ++;
			int a = l(tmp1, tmp2);int b = l(tmp2, tmp3);int c = l(tmp1, tmp3);
			printf("\n%d", (l(tmp1, tmp2) + l(tmp2, tmp3) + l(tmp1, tmp3))>> 1);
		}
		ok = true;
	}
	return 0;
}
时间: 2024-10-12 21:42:01

ZOJ3195 Design the city [2017年6月计划 树上问题04]的相关文章

HDU3887 Counting Offspring [2017年6月计划 树上问题03]

Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2809    Accepted Submission(s): 981 Problem Description You are given a tree, it’s root is p, and the node is numbered from 1

洛谷P3459 [POI2007]MEG-Megalopolis [2017年6月计划 树上问题02]

[POI2007]MEG-Megalopolis 题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the Postman, who once roamedthe country lanes amidst sleepy hamlets and who now dashes down the motorways. But it is those strolls inthe days of

[zoj3195]Design the city(LCA)

解题关键:求树上三点间的最短距离. 解题关键:$ans = (dis(a,b) + dis(a,c) + dis(b,c))/2$ 1 //#pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<

RQNOJ PID192 梦幻大PK [2017年6月计划 二分图02]

PID192 / 梦幻大PK ☆ 提交你的代码 查看讨论和题解 你还木有做过哦 我的状态 查看最后一次评测记录 质量 7 题目评价 质量 7 ★★★★★ ★★★★☆ ★★★☆☆ ★★☆☆☆ ★☆☆☆☆ 50% 0% 25% 0% 25% ★ ★ ★ ★ ☆ 通过人数 754 / 2273 通过统计 最短耗时 0ms 最小内存 0KB 匹配 题目标签 类型 匹配 题目描述 难得到了生日,正逢上班里面一年一度的梦幻大PK,分2组对拼.但是由于某种原因,参加PK的第1组中有些人不能和第2组人PK.可能

2017年7月计划

6月的最后一天,我完成了六月计划,打卡 7月07日~14日将在郑州河南省实验度过 7月15日~22日将在济南清北学堂度过 7月25日~8月2日将在日照一中度过 8月05日~11日将在青岛二中度过 于是...定下如下计划: 1.动态规划百题斩开启  难度在提高及以上.100道题, 包括: 状压DP                                    15道 区间DP                                    10道 树上DP 10道 数位DP 10道

洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]

P2723 丑数 Humble Numbers 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括,p1.p1*p2.p1*p1.p1*p2*p3...(还有其 它).该集合被称为S集合的“丑数集合”.注意:我们认为1不是一个丑数. 题目描述 你的工作是对于输入的集合S去寻找“丑数集合”中的第N个“丑数”.所有答案可以用longint(32位整数)存储. 补充:丑数集合中每个数从小到大排列,每个丑

洛谷P1062 数列 [2017年6月计划 数论03]

P1062 数列 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… (该序列实际上就是:3^0,3^1,3^0+3^1,3^2,3^0+3^2,3^1+3^2,3^0+3^1+3^2,…) 请你求出这个序列的第N项的值(用10进制数表示). 例如,对于k=3,N=100,正确答案应该是981. 输入输出格式 输入格式: 输入文件只有1行,为2个正整数,用一个空格隔开

【洛谷】P2073 送花 [2017年6月计划 线段树01]

P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地向里面添加花.他有以下几种操作: 操作 含义 1 W C 添加一朵美丽值为W,价格为C的花. 3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花. 2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花. -1 完成添加与删除,开始包

【巨坑】 二分图学习笔记 [2017年6月计划 学习二分图]

1.二分图:    ①把一个图的点集划为两个不相交的集合U,V,使得每一条边都连接U,V中的节点. ②(等价定义,更方便看)不含边数为奇数的环的图 2.匹配(matching): 边集,每一条边所连顶点互不相同 3.最大匹配: 所含边数最大的匹配 4.完美匹配: 所有顶点都被匹配,完美匹配一定是最大匹配. 5.交替路: 从一个非匹配点出发,依次走非匹配边,匹配边,非匹配边....交替走,形成交替路 6.增广路: 从一个非匹配点出发,走交替路,经过另一个非匹配点,则这条路径叫做增广路   增广路特