HDU-2586-How far away(LCA Tarjan离线算法)

链接:https://vjudge.net/problem/HDU-2586

题意:

勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,
修建小镇的时候,为了让小镇有特色,镇长特地只修了n-1条路,并且规定说,所有在勇气小镇的村民,每一次出门必须规划好路线, 
路线必须满足在到达终点之前绝对不走回头路。每个人都要这样,不然那个人就不配在小镇生活下去,因为他没有这个勇气。
事实上,这并不能算一项挑战,因为n-1条路已经连通了每户人家,不回头地从起点到终点,只是一个时间上的问题。
由于小镇上的福利特别好,所以小懒入住了这个小镇,他规划了m次的行程,每次从L房屋到R房屋,他想问你他每次从L房屋到R房屋需要走多远的路。

思路:

Tarjan离线算法, 第i个查询的最短路为dis[s[i]]+dis[e[i]]-2*dis[fas[i]]

代码:

#include <iostream>
#include <memory.h>
#include <string>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
#include <cstdio>
#include <set>
#include <iterator>
#include <cstring>
using namespace std; typedef long long LL;
const int MAXN = 4e4+10;
struct Node
{
int from_, to_, dist_;
Node(int from, int to, int dist):from_(from), to_(to), dist_(dist){}
};
vector<Node> G[MAXN];
int fa[MAXN], dis[MAXN];
int vis[MAXN], fas[MAXN];
int s[MAXN], e[MAXN];
int n, m, l, r, v;
int root, res; int Get_F(int x)
{
if (fa[x] == x)
return x;
fa[x] = Get_F(fa[x]);
return fa[x];
} void Merge(int u, int v)
{
int tv = Get_F(v);
int tu = Get_F(u);
if (tv != tu)
fa[v] = u;
} void Tarjan(int u)
{
vis[u] = 1;
for (int i = 1;i <= m;i++)
{
if (s[i] == u && vis[e[i]] == 1)
fas[i] = Get_F(e[i]);
if (e[i] == u && vis[s[i]] == 1)
fas[i] = Get_F(s[i]);
}
for (int i = 0;i < G[u].size();i++)
{
Node node = G[u][i];
if (!vis[node.to_])
{
dis[node.to_] = dis[node.from_] + node.dist_;
Tarjan(node.to_);
Merge(node.from_, node.to_);
}
}
} void init()
{
for (int i = 1;i <= n;i++)
{
G[i].clear();
fa[i] = i;
}
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(vis));
} int main()
{
ios::sync_with_stdio(false);
cin.tie(0); int t;
cin >> t;
while (t--)
{
cin >> n >> m;
init();
for (int i = 1;i < n;i++)
{
cin >> l >> r >> v;
G[l].emplace_back(l, r, v);
G[r].emplace_back(r, l, v);
}
for (int i = 1;i <= m;i++)
{
cin >> l >> r;
s[i] = l;
e[i] = r;
}
dis[1] = 0;
Tarjan(1);
for (int i = 1;i <= m;i++)
{
cout << dis[s[i]]+dis[e[i]]-2*dis[fas[i]] << endl;
}
} return 0;
}

  

上一篇:godaddy如何联系客服帮助的技巧和方法


下一篇:python三级菜单实例(傻瓜版和进阶版)