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 对于每一段文本,输出其中的汉 ...
随机推荐
- 《深入理解java虚拟机》笔记(4)对象已死吗
一.垃圾回收器回收的对象 虚拟机内存区域中程序计数器.虚拟机栈.本地方法栈随线程而生,随线程而灭.这3个区域内存分配和回收都具备确定性.因此不需要过多考虑回收问题. 而Java堆和方法区不一样,这部分 ...
- css常用操作
对齐操作 1.使用margin属性进行水平对齐 margin-left:auto; margin-right:auto; 2.使用position属性进行左右对齐 3.使用fl ...
- 如何解决Eureka Server不踢出已关停的节点的问题?
如何解决Eureka Server不踢出已关停的节点的问题? eureka端: eureka.server.enable-self-preservation ...
- 织梦修改“dedecms提示信息”
1.根目录下include文件夹,找到common.func.php: 2.根目录下dede文件夹(管理目录默认dede),找到sys_data_done.php: 3.打开以上2个.php文件,把“ ...
- 如何在Android Studio中导入JNI生成的.so库
由于在原来的ADT的Eclipse环境中,用ndk_build工具生成了相应的各个.so库文件之后,eclipse工具就会自动把这些库导入到apk中.而Android Studio目前为止(0.86版 ...
- MySQL++简单使用记录.md
#1.简介 MySQL++ is a powerful C++ wrapper for MySQL’s C API. Its purpose is to make working with queri ...
- (转)!注意:PreTranslateMessage弹出框出错
dlg.DoModal()截住了界面消息,所以返回时原来的pMsg的内容已经更改了,消息,窗口句柄都不在是if以前的值了,而且窗口句柄应该是对话框里的子窗口的句柄,所以调用CFrameWnd::Pre ...
- Python3+Selenium3+webdriver学习笔记13(js操作应用:弹出框无效如何处理)
#!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记13(js操作应用:弹出框无效如何处理)'''from sel ...
- Windows7(x86) xampp php5.5 imagick install
I hate windows. 1. 下载安装 ImageMagick, 选择合适您电脑的版本,我下载的是: ImageMagick-6.8.9-1-Q16-x86-dll.exe http://ww ...
- oracle 11g r2安装
安装环境:windows 7 安装版本:Oracle_win32_11gR2 目的:用于模拟服务器环境,学习Oracle操作 1. 下载oracle 11g r2,下载地址:www.oracle.co ...