HDU:2586-How far away
How far away
Time limit1000 ms
Memory limit32768 kB
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
解题心得:
- 题意就是给你一个双向图,每两点之间只有一条路径(其实就是一颗树),任意问你两点,要求输出两点间的最小距离。两种做法:
- 第一种就是直接跑暴力的dfs,复杂度也就是n*m最大8e6,很简单就跑过了。
- 第二种就是用LCA,两点之间最短的距离就是两点经过最近公共祖先形成的一条路。具体做法可以先预处理一下每个点到根节点的距离,存在数组dis里面,假如询问a,b之间的最小距离,就可以先得出最近公共祖先c然后答案就是dis[a] + dis[b] - 2*dis[c]。
- 然后就是双向边怎么建成一棵树的问题,可以用邻接表存图,存双向边,在使用的时候任意选一个点为根节点,使用过的点就标记上,这样就可以形成一棵树,因为每两点之间只选择一个方向的边。
dfs跑暴力:
#include<stdio.h>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 4e4+100;
bool vis[maxn],flag;
int n,m,ans,a,b;
vector <pair<int,int> > ve[maxn];
void init()
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=0;i<=n+1;i++)
ve[i].clear();
for(int i=1;i<n;i++)
{
int a,b,len;
scanf("%d%d%d",&a,&b,&len);
//邻接表存图
ve[a].push_back(make_pair(b,len));
ve[b].push_back(make_pair(a,len));
}
}
void dfs(int pos,int sum_len)
{
if(vis[pos] || flag)
return ;
vis[pos] = true;
if(pos == b)
{
printf("%d\n",sum_len);
flag = true;
return;
}
for(int i=0;i<ve[pos].size();i++)
{
pair<int,int> p;
p = ve[pos][i];
dfs(p.first,sum_len + p.second);
}
}
void solve()
{
while(m--)
{
flag = false;
memset(vis,0,sizeof(vis));
scanf("%d%d",&a,&b);
dfs(a,0);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
solve();
}
}
LCA(tarjan写法)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e4+100;
vector <pair<int,int> > ve[maxn];
int vis[maxn],n,father[maxn],sum[maxn],m,a,b;
bool flag;
void init()
{
memset(father,0,sizeof(father));
memset(vis,0,sizeof(vis));
memset(sum,0,sizeof(sum));
for(int i=0; i<=n; i++)
ve[i].clear();
for(int i=1; i<n; i++)
{
int a,b,len;
scanf("%d%d%d",&a,&b,&len);
ve[a].push_back(make_pair(b,len));
ve[b].push_back(make_pair(a,len));
}
}
void dfs(int pos,int len)
{
vis[pos] = true;
sum[pos] = len;
for(int i=0; i<ve[pos].size(); i++)
{
int v = ve[pos][i].first;
if(!vis[v])
dfs(v,len+ve[pos][i].second);
}
return ;
}
int find(int x)
{
if(x == father[x])
return x;
return father[x] = find(father[x]);
}
void tarjan(int pos)//跑tarjan
{
vis[pos] = true;
father[pos] = pos;
if(flag)
return;
for(int i=0; i<ve[pos].size(); i++)
{
int v = ve[pos][i].first;
if(!vis[v])
{
tarjan(v);
father[v] = pos;
}
if(flag)
return ;
}
if(pos == a || pos == b)
{
if(pos != a)
swap(a,b);
if(father[b])
{
int ans = find(father[b]);
printf("%d\n",abs(sum[a]+sum[b]-sum[ans]*2));
flag = true;
}
}
}
void query()
{
while(m--)
{
flag = false;
memset(father,0,sizeof(father));
memset(vis,0,sizeof(vis));
scanf("%d%d",&a,&b);
tarjan(1);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
dfs(1,0);//先dfs预处理
query();
}
}
HDU:2586-How far away的更多相关文章
- HDU:过山车(二分图最大匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=2063 题意:有m个男,n个女,和 k 条边,求有多少对男女可以搭配. 思路:裸的二分图最大匹配,匈牙利算法. 枚 ...
- HDU:Gauss Fibonacci(矩阵快速幂+二分)
http://acm.hdu.edu.cn/showproblem.php?pid=1588 Problem Description Without expecting, Angel replied ...
- HDU:2846-Repository
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2846 Repository Time Limit: 2000/1000 MS (Java/Others) ...
- HDU:1251-统计难题(字典树模板,动态建树,静态建树)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memor ...
- HDU:2767-Proving Equivalences(添边形成连通图)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 4000/2000 MS (Ja ...
- HDU:2255-奔小康赚大钱(KM算法模板)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Mem ...
- AC自动机(Aho-Corasick automation)模板 HDU:2222
#include <iostream> #include <cstdio> #include <cstring> #include <queue> us ...
- HDU ACM 2586 How far away ?LCA->并查集+Tarjan(离线)算法
题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w.有m次询问,每次询问房子a,b之间的距离是多少. 分析:近期公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次 ...
- hdu:2036.改革春风吹满地
Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分地.谢谢!(乐队奏乐)” 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里 ...
- hdu:2030.汉字统计
Problem Description 统计给定文本文件中汉字的个数. Input 输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本. Output 对于每一段文本,输出其中的汉 ...
随机推荐
- Storm概念学习系列之并行度与如何提高storm的并行度
不多说,直接上干货! 对于storm来说,并行度的概念非常重要!大家一定要好好理解和消化. storm的并行度,可以简单的理解为多线程. 如何提高storm的并行度? storm程序主要由spout和 ...
- java获取服务器一些信息的方法
request.getServletContext().getRealPath("/") 获取项目所在服务器的全路径,如:D:\Program Files\apache-tomca ...
- Servlet 示例
引入jar包: servlet-api.jar ParameterServlet.java package com.mousewheel.springmvc; import java.io.IOExc ...
- java内存分配(堆、栈、常量池)
Java内存分配: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,以及成员方法中的局部变量 ◆堆:存放对象本身(成员变量+成员方法的引用) ◆静态域:存放在对象中用static ...
- ajax取到数据后如何拿到data.data中的属性值
今天遇到的ajax取到数据后如何拿到data.data中的属性值的问题 比如拿到了数据 我要取出data中的name 题外话:当然取名最好别取什么奇怪的xiaobi
- Canvas基本绘画学习
学好Canvas,从简单开始.下面是一些Canvas入门最基本的实例分享: <!DOCTYPE html> <html> <head lang="en" ...
- [20190620]日常学习记录(三)-初识promise及vuex
在学习promise之前重温了Ajax的原生js实现, 在原生js中发送一个http请求首先new XMLHttpRequest() 然后定义状态变更事件 浏览器监听请求的状态,触发不同状态下相应的代 ...
- 织梦DEDECMS会员中心发布文章修改提示"数据校验不对,程序返回"
一.文件:member/inc/inc_archives_function.php 找到函数 function PrintAutoFieldsEdit(&$fieldset, &$fi ...
- 读写属性/if判断那点事/数组
读写属性属性操作注意事项 js中不允许出现"-".所以font-size变成fontSize/margin-top变成marginTop. Op.style.with=" ...
- 大会聚焦 | 开源技术盛会LinuxCon首次来到中国,大咖齐聚关注业界动态
2017年6月19-20日,开源技术盛会LinuxCon + ContainerCon + CloudOpen(LC3)首次在中国举行.两天议程满满,包括 17 个主旨演讲.8 个分会场的 88 场技 ...