Lh of a simple graph theory
http://10.64.70.166/problem/1112
Description
As we all know, the training team lh students txdy, one day he reads the code, suddenly began to hum RAP r A the p-, yo, yo yo, you see this bowl it big and round, just like the title it short and difficult , SKR S K R & lt, SKR S K R & lt.
LH L H a graph theory in addressing the problem:
There is known a n- n-point undirected graph, there FIG. M m edges, each edge weight value W_i W I .
LH L H wants to know, from his point a come point a b b, the minimum length of the longest side of the walk is how much?
Input
The first line of the input three positive integers n-, m, Q n- , m , Q, respectively, have n- n-point m m edges and Q Q times interrogation.
Subsequently m m rows, each row having three numbers are u_i U I , V_I V I , W_i W I represents from the point U U to point V V with a side length of a path W W.
Next Q Q rows, each row having two numbers a a, b b, represents LH L H that he wants to know from a walk a b a minimum value of the longest side length b in walking.
Output
Output Q Q lines, each a positive integer, from the point that he a come a point A B B, the minimum length of the longest side of the walk is.
Sample Input 1
6 6 8 1 2 5 2 3 4 3 4 3 1 4 8 2 5 7 4 6 2 1 2 1 3 1 4 2 3 2 4 5 1 6 2 6 1
Sample Output 1
5 5 5 4 4 7 4 5
Hint
1≤n≤15000
1≤M≤30000
1≤wi≤1000000000
1≤q≤20000
This topic is more typical tree diagram turn, this sounds like the UVA 11354
You use the minimum spanning tree diagram into a tree, and then use the LCA process tree
#include <cstring> #include <cstdlib> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <queue> #include <iostream> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 3e4 + 100; int dp[maxn][30]; ll gw[maxn][30]; int deep[maxn]; int n, m, q, N; struct node { int from,to; ll dist; node(int from=0,int to=0,ll dist=0):from(from),to(to),dist(dist){} }exa[maxn]; vector<node>vec[maxn]; int f[maxn]; int findx(int x) { return f[x] == x ? x : f[x] = findx(f[x]); } void unite(int x,int y) { x = findx(x); y = findx(y); if (x == y) return; f[x] = y; } bool same(int x,int y) { return findx(x) == findx(y); } bool cmp(node a,node b) { return a.dist < b.dist; } void dfs(int s) { for(int i=1;i<=N;i++) { dp[s][i] = dp[dp[s][i - 1]][i - 1]; gw[s][i] = max(gw[s][i - 1], gw[dp[s][i - 1]][i - 1]); } int len = vec[s].size(); for(int i=0;i<len;i++) { node e = vec[s][i]; if(e.to!=dp[s][0]) { deep[e.to] = deep[s] + 1; dp[e.to][0] = s; gw[e.to][0] = e.dist; dfs(e.to); } } } ll LCA(int x,int y) { if (x == y) return 0; if (deep[x] > deep[y]) swap(x, y); ll ans = 0; for(int i=N;i>=0;i--)//抬到同一高度 { if(deep[x]<deep[y]&&deep[dp[y][i]]>=deep[x]) { ans = max(ans, gw[y][i]); y = dp[y][i]; } } For ( int I = N; I> = 0 ; i--) // together go up { IF (DP [X] [I] =! DP [Y] [I]) { ANS = max (ANS, GW [X] [I]); ANS = max (ANS, GW [Y] [I]); X = DP [X] [I]; Y = DP [Y] [I]; } } IF (X! Y =) // last step { ANS = max (ANS, GW [X] [ 0 ]); ANS = max (ANS, GW [Y] [ 0 ]); } return ans; } int main() { cin >> n >> m >> q; for(int i=1;i<=m;i++) { int a, b; ll w; cin >> a >> b >> w; exa[i] = node(a, b, w); } for (int i = 1; i <= n; i++) f[i] = i; sort(exa + 1, exa + 1 + m, cmp); for(int i=1;i<=m;i++) { int x = exa[i].from, y = exa[i].to; if (same(x, y)) continue; unite(x,y); vec[x].push_back(node(x, y, exa[i].dist)); vec[y].push_back(node(y, x, exa[i].dist)); } N = (log(n + 0.0)) / log(2.0); deep[1] = 0; dfs(1); for(int i=1;i<=q;i++) { int x, y; cin >> x >> y; ll ans = LCA(x, y); cout << ans << endl; } return 0; }