任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2586

How far away ?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24439    Accepted Submission(s): 9739

Problem Description
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
 
Input
First line is a single integer T(T<=10), indicating the number of test cases.
  For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
  Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
 
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
 
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3

2 2
1 2 100
1 2
2 1

 
Sample Output
10
25
100
100

题意概括:

给一颗 N 个结点,N-1条边的树,和 M 次查询(离线)

解题思路:

要查询两点到最近公共祖先的距离和,首先要预处理出根结点到各个结点的距离(DFS)

然后 Tarjan 找出最近的公共祖先,两个结点到根结点的距离之和减去两倍的最近公共祖先到根结点的距离就是该查询的答案了。

AC code:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define INF 0x3f3f3f3f
#define LL long long
const int MAX_N = 4e4+;
using namespace std; struct Edge{int v, nxt, w;}edge[MAX_N<<]; //静态邻接表
struct Query
{
int v, id;
Query(){};
Query(int _v, int _id):v(_v), id(_id){};
}; vector<Query> q[MAX_N]; // !!! //查询关系动态二维矩阵 int head[MAX_N], cnt; //静态邻接表头节点,边数
int dis[MAX_N]; //各结点到根结点的距离
int fa[MAX_N]; //并查集 祖先数组
bool vis[MAX_N], in[MAX_N]; //深搜用,找根结点用
int ans[MAX_N]; // !!! //各查询答案
int N, M; //结点数,查询数 void init()
{
memset(head, -, sizeof(head)); //初始化
memset(vis, false, sizeof(vis));
memset(in, false, sizeof(in));
memset(dis, , sizeof(dis));
memset(ans, , sizeof(ans));
cnt = ;
} void AddEdge(int from, int to, int weight) //静态邻接表加边操作
{
edge[cnt].v = to;
edge[cnt].w = weight;
edge[cnt].nxt = head[from];
head[from] = cnt++;
} int getfa(int x) //找祖先
{
int root = x;
while(fa[root] != root) root = fa[root]; int tmp;
while(fa[x] != root){
tmp = fa[x];
fa[x] = root;
x = tmp;
}
return root;
} void dfs(int s) //预处理各根结点到祖先的距离
{
int rt = s;
for(int i = head[s]; i != -; i = edge[i].nxt){
dis[edge[i].v] = dis[rt] + edge[i].w;
dfs(edge[i].v);
}
} void Tarjan(int s) // LCA
{
int root = s;
fa[s] = s;
for(int i = head[s]; i != -; i = edge[i].nxt){
int Eiv = edge[i].v;
Tarjan(Eiv);
fa[getfa(Eiv)] = s;
}
vis[s] = true;
for(int i = ; i < q[s].size(); i++){
if(vis[q[s][i].v] && !ans[q[s][i].id]){
ans[q[s][i].id] = dis[q[s][i].v] + dis[s] - *dis[getfa(q[s][i].v)];
}
}
} int main()
{
int T_case;
scanf("%d", &T_case);
while(T_case--){
init();
scanf("%d %d", &N, &M);
for(int i = , u, v, w; i < N; i++){ //建树
scanf("%d %d %d", &u, &v, &w);
AddEdge(u, v, w);
in[v] = true;
} for(int i = , u, v; i <= M; i++){ //储存查询信息(离线)
scanf("%d %d", &u, &v);
q[u].push_back(Query(v, i));
q[v].push_back(Query(u, i));
} int root = ;
for(int i = ; i <= N; i++) if(!in[i]){root = i; break;} //找树根结点 dfs(root); //预处理
Tarjan(root); //LCA for(int i = ; i <= M; i++){
printf("%d\n", ans[i]);
}
//puts("");
}
return ;
}

最新文章

  1. Mybatis学习记录
  2. Notepad++ HTML格式化
  3. 在matlab中进行地理坐标和像素坐标的相互转换
  4. HD2157How many wasy??(十大矩阵问题之八 + 邻接矩阵的应用)
  5. 【python】环境变量的配置
  6. 黄聪:wordpress更新失败‘C:\Windows\TEMP/wordpress.tmp’,更换临时保存路径的解决办法
  7. 【AsyncTask整理 1】 AsyncTask几点要注意的地方
  8. 51nod1270 数组的最大代价(简单dp)
  9. Lua for windows中SciTe开启支持python的方法
  10. 友元(friend)--初学篇
  11. python 模块导入
  12. math.h中的常量
  13. php 文件操作中几种方法整理
  14. YouTube为什么打不开?以及简便的訪问的方法/解决方式!
  15. Python 阿里大于发送手机验证码
  16. Stochastic Gradient Descent 随机梯度下降法-R实现
  17. java遍历实体类的属性和值
  18. topcoder srm 410 div1
  19. tensorflow serving 中 No module named tensorflow_serving.apis,找不到predict_pb2问题
  20. python-状态模式

热门文章

  1. 牛客网Java刷题知识点之UDP协议是否支持HTTP和HTTPS协议?为什么?TCP协议支持吗?
  2. 案例40-层与层之间的解耦(面向接口编程)BeanFactory
  3. 负载均衡服务器中存在大量的TIME_WAIT怎么解决
  4. 新建maven工程index.jsp页面报错
  5. Programmer Competency Matrix--ref--http://sijinjoseph.com/programmer-competency-matrix/
  6. 【mysql】mysql数据库安装
  7. [转] CentOS下添加用户并且让用户获得root权限
  8. C++程序设计基础(5)sizeof的使用
  9. CentOS安装nginx方法命令教程
  10. VueConf 全球首届Vue.js开发者大会资料整理