譚鬆鬆的旅遊計畫 LCA 求最短路

2021-07-31 08:20:08 字數 3107 閱讀 3338

譚鬆鬆是乙個愛旅遊的人,他非常的熱愛旅遊,即便身體被掏空也要堅持旅遊。喵蛤王國由n個城市組成,由n-1條道路連通,每條道路長度為ci,使得任意兩座城市都能相互到達。譚鬆鬆有m個旅遊計畫,每個旅遊計畫有乙個起點ai,乙個終點bi,所以譚鬆鬆想知道,對於每個旅遊計畫,從起點到終點的最短路長度為多少?

input

第一行兩個整數n(2≤n≤100000,),m(1≤m≤100000),表示城市個數,譚鬆鬆的旅遊計畫個數。

接下來n-1行,每行三個整數li,ri,ci(1≤ci≤10000),表示li號城市和ri號城市之間有一條長度為ci的道路。

接下來m行,每行兩個整數ai,bi表示旅遊計畫的起點和終點。

output

輸出m行,表示每個旅遊計畫的最短距離。

sample input

7 6

1 2 5

1 3 4

3 7 7

2 4 4

2 5 3

5 6 2

1 2

4 7

6 3

3 2

5 4

7 6

sample output

5 20

14 9

7 21

hint

題解: 首先一看n的大小,就知道沒辦法用djk或者別的求最短路的演算法,

學習了— 可以用lca (最近公共祖先來求解最短路)

lca 就是自己定義乙個根節點建樹

**

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define m 100000+100

using

namespace

std;

void read(int &x)

struct edge;

vector

g[m];

int pre[m];int n,m,q;

int ranks[m],value[m];

void getmap()

); g[b].push_back();

}}queue

q;void bfs(int st) // 用bfs 跑出 每個子節點的深度和每個點的父節點} }

}int lca(int st,int ed) //這裡用的是步近法來求最近公共祖先,還有更多有效率的演算法求最近公共祖先這裡就不列舉了

return sum;

}int main()

return

0;}

**

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define mod 100009

#define ll long long

#define m 100000+100

using

namespace

std;

struct edge ;

vector

g[m];

int n,m;

int pre[m];

int ranks[m];

int cost[m];

void init(){}

void getmap()

) ; g[b].push_back() ;

} } void dfs(int now,int par,int depth) // 用dfs跑

} }int lca(int a,int b) // 求兩個節點的最短距離

return sum;

}int main()

return

0;}

2017 5.27 最近學了,lca轉rmq (不會?點我 ) 趕緊練一下

設dis[x]為樹根到x節點的路程,所以只要求出a,b的lca,答案就是dis[a]+dis[b]-2*dis[lca(a,b)]

dis的記錄在遍歷樹的時候可以求得。

**

#include 

#include

#include

#include

#define maxn 100000+100

#define maxm 100000

using

namespace

std;

struct edge

;edge edge[maxn<<1];

int head[maxn], edgenum;

int vs[maxn<<1];//第i次dfs訪問節點的編號

int depth[maxn<<1];//第i次dfs訪問節點的深度

int id[maxn];//id[i] 記錄在vs陣列裡面 i節點第一次出現的下標

int dfs_clock;//時間戳

int n, m, q;//點數 邊數 查詢數

int dp[maxn<<1][20];//dp[i][j]儲存depth陣列 以下標i開始的,長度為2^j的區間裡 最小值所對應的下標

int dist[maxn];

void init()

void addedge(int u, int v,int c)

; edge[edgenum] = e;

head[u] = edgenum++;

}void getmap()

void dfs(int u, int fa, int d)//當前遍歷點以及它的父節點 遍歷點深度

}void find_depth()

void rmq_init(int nn)//預處理 區間最小值

}}int query(int l, int r)

int lca(int u, int v)

void solve()

}int main()

最短路 求最長最短路,求最短路的路徑

hdu 1595 find the longest of the shortest include include include include include include include include include include include include include defi...

演算法 LCA最近公共祖先求最短路演算法

自己研究的扯淡演算法,不知道有沒有重複的 演算法定義及適用範圍 lca 最近公共祖先 是一種樹上的演算法,求任意兩點a,b的最近公共祖先。一幅n個頂點,n 1條邊的圖就認可以認為這幅圖是一棵樹。如下圖是一幅n個頂點,n 1條邊的圖,即一棵樹。隨機取出兩個點x,y,找到他們的最近公共祖先,即點1。在尋...

求單源的最短路徑

用鄰接表的方法儲存網 include include include include define inf 0x3f3f3f define node max 20 using namespace std vector path node max 儲存路徑 int d node max 儲存路徑長度 ...