【Lca 離線Tarjan演算法】hdu 2586 How far away ?
LCA 離線Tarjan演算法
題意: 對於一個圖,n(<=40000)個點,給出n-1條邊(u,v,w,), m(<=200)個詢問給出兩點,問其最短距離。
離線演算法(必然先存所有詢問);
dfs:
1. 遍歷到當前點,創造一個當前點的集合
2. 對於遍歷完的子樹,將其根節點的集合加入其父節點所在的集合。
3. 對於詢問的兩點,遍歷到一點,如果另一點已經被遍歷,那麼另一點已經加入集合的最高那一點即為最近公共祖先。
4. 因為另一點可能在此點的子樹上,所以詢問的答案應該在遍歷完其子樹後執行。
注意: 問題的記錄最好用前向星寫吧。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
//#pragma comment(linker, "/STACK:102400000,102400000")
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF=0x3f3f3f3f;
const LL mod = 1e9+7;
const int N = 100000+10;
const int M = 2500000;
struct Node
{
int from;
int to;
int val;
int next;
};
int dir[N],fa[N],vis[N];
vector<Node> ma[N]; //vector 記錄圖
Node query[N*2];
int head[N];
int ans[N];
void addquery(int u,int v,int &top)
{
query[++top].from = u; query[top].to = v; query[top].next = head[u];
head[u] = top;
query[++top].from = v; query[top].to = u; query[top].next = head[v];
head[v] = top;
}
int Find(int n)
{
if(fa[n] != n){
fa[n] = Find(fa[n]);
}
return fa[n];
}
void dfs(int n,int dist) //dfs處理需要陣列
{
fa[n] = n;
vis[n]=true;
dir[n]=dist;
for(int i = 0; i < ma[n].size(); i++){
Node temp = ma[n][i];
if(!vis[temp.to]){
dfs(temp.to,dist+temp.val);
fa[temp.to] = n;
}
}
for(int i = head[n]; i != -1; i=query[i].next){
int v = query[i].to;
if(vis[v]){
int pa = Find(v);
//query[i].val = dir[n]+dir[v]-2*dir[pa];
ans[(i-1)/2] = dir[n]+dir[v]-2*dir[pa];
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
ma[i].clear();
}
for(int i = 1; i < n; i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Node temp;
temp.to = v; temp.val = w;
ma[u].push_back(temp);
temp.to = u; temp.val = w;
ma[v].push_back(temp);
}
int top = 0;
for(int i = 0; i < m; i++){
int u,v;
scanf("%d%d",&u,&v);
addquery(u,v,top);
}
dfs(1,0);
for(int i = 0; i < m; i++){
printf("%d\n",ans[i]);
}
}
return 0;
}
相關文章
- 【Lca 線上st演算法】hdu 2586 How far away ?演算法
- POJ 1330 LCA最近公共祖先 離線tarjan演算法演算法
- LCA(倍增與Tarjan)
- LCA最近公共祖先 線上演算法和離線演算法 模板演算法
- hdu4288 離線處理線段樹
- hdu 4368 樹狀陣列 離線維護陣列
- Lca相關演算法演算法
- HDU 2767 Proving Equivalences Tarjan 強連通縮點UI
- HDU5139 Formula (找規律+離線處理)ORM
- HDU5200 Trees (離線處理)
- HDU 5200 Tree (離線並查集)並查集
- Tarjan演算法_縮點演算法
- HDU 3333 Turing Tree(線段樹+離線操作)
- HDU1213-How Many Tables
- tarjan—演算法的神(一)演算法
- tarjan演算法求scc & 縮點演算法
- 強連通分量(Tarjan演算法)演算法
- 連通圖與Tarjan演算法演算法
- Tarjan 演算法學習筆記演算法筆記
- bzoj3626: [LNOI2014]LCA(離線處理+樹鏈剖分)
- HDU 1213 How Many Tables(並查集)並查集
- lca
- Tarjan演算法(強連通分量分解)演算法
- HDU 2157 How many ways?? (矩陣快速冪)矩陣
- 動態規劃 hdu 1978 How many ways動態規劃
- HDU 5862 Counting Intersections(樹狀陣列+掃描線+離散化)陣列
- 圖論——強連通分量(Tarjan演算法)圖論演算法
- 求 LCA
- Tarjan
- 演算法學習筆記(5): 最近公共祖先(LCA)演算法筆記
- Tarjan演算法求強連通分量總結演算法
- 全網最!詳!細!Tarjan演算法講解。演算法
- 強連通分量-tarjan演算法模板詳解演算法
- 強連通演算法--Tarjan個人理解+詳解演算法
- 一文輕鬆搞定 tarjan 演算法(二)演算法
- 連通圖演算法詳解之① :Tarjan 和 Kosaraju 演算法演算法
- HDU 3038 How Many Answers Are Wrong (帶權並查集)並查集
- Oracle Far Sync例項Oracle