拯救邦德 - 树上递增
Posted ak-ls
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拯救邦德 - 树上递增相关的知识,希望对你有一定的参考价值。
额(⊙o⊙)…,百度翻译是这样的
Sample Input
4 5
1 2 10
1 3 20
1 4 100
2 4 30
3 4 10
2
1 4
4 1
2 1
1 2 100
1 1 2
Sample Output
20
20
#include <bits/stdc++.h> using namespace std; // #define INF 0x3f3f3f3f #define MAXN 100010 // #define MAXM 5010 inline int read() { int x = 0,ff = 1;char ch = getchar(); while(!isdigit(ch)) { if(ch == ‘-‘) ff = -1; ch = getchar(); } while(isdigit(ch)) { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * ff; } inline void write(int x) { if(x < 0) putchar(‘-‘),x = -x; if(x > 9) write(x / 10); putchar(x % 10 +‘0‘); } int a,b,c,cnt = 0,deep[MAXN],fa[MAXN],mxcost[MAXN][50]; int lin[MAXN],tot = 0,p[MAXN][50],cost[MAXN],vis[MAXN]; // queue < int > q; struct node { int x,y,v; }m[MAXN]; struct edge { int y,v,next; }e[MAXN]; inline void add(int xx,int yy,int vv) { e[++tot].y = yy; e[tot].v = vv; e[tot].next = lin[xx]; lin[xx] = tot; } inline bool cmp(node x,node y) { return x.v < y.v; } inline int get(int x) { return fa[x] == x ? x : fa[x] = get(fa[x]); } inline void clear() { // queue < int > empty; // swap(empty,q); tot = 0; memset(m,0,sizeof(e)); memset(lin,0,sizeof(lin)); memset(e,0,sizeof(e)); memset(deep,0,sizeof(deep)); memset(cost,0,sizeof(cost)); memset(mxcost,0,sizeof(mxcost)); memset(vis,false,sizeof(vis)); } void Kruskal() { cnt = 0; for(int i = 1;i <= a;++i) fa[i] = i; sort(m + 1,m + b + 1,cmp); for(int i = 1;i <= b && cnt < a - 1;++i) { int x = get(m[i].x),y = get(m[i].y); if(x != y) { fa[x] = y; cnt++; add(m[i].x,m[i].y,m[i].v); add(m[i].y,m[i].x,m[i].v); } } } void BFS() { queue < int > q; memset(fa,0,sizeof(fa)); deep[1] = 1; q.push(1); fa[1] = -1; while(!q.empty()) { int x = q.front(); q.pop(); for(int i = lin[x],y;i;i = e[i].next) { if(deep[y = e[i].y]) continue; fa[y] = x; deep[y] = deep[x] + 1; cost[y] = e[i].v; q.push(y); } } } void make() { for(int i = 1;i <= a;++i) { p[i][0] = fa[i]; mxcost[i][0] = cost[i]; for(int j = 1;(1 << j) <= a;++j) p[i][j] = -1; } for(int i = 1;(1 << i) <= a;++i) { for(int j = 1;j <= a;++j) { int y = p[j][i - 1]; if(y != -1) { p[j][i] = p[y][i - 1]; mxcost[j][i] = max(mxcost[j][i - 1],mxcost[y][i - 1]); } } } } int lca(int x,int y) { int t = 0,ans = 0; if(deep[x] > deep[y]) swap(x , y); while((1 << t) <= a) ++t; --t; for(int i = t;i >= 0;--i) if(deep[p[y][i]] >= deep[x]) { ans = max(ans,mxcost[y][i]); y = p[y][i]; } if(x == y) return ans; for(int i = t;i >= 0;--i) { if(p[x][i] != p[y][i]) { ans = max(ans,mxcost[x][i]); ans = max(ans,mxcost[y][i]); x = p[x][i]; y = p[y][i]; } } ans = max(ans,mxcost[x][0]); ans = max(ans,mxcost[y][0]); return ans; } int main() { int T = 0; while(scanf("%d%d",&a,&b) == 2) { clear(); for(int i = 1;i <= b;++i) { m[i].x = read(); m[i].y = read(); m[i].v = read(); } Kruskal(); memset(fa,0,sizeof(fa)); BFS(); make(); c = read(); if(++T != 1) putchar(‘ ‘); while(c--) { int x,y; x = read(); y = read(); write(lca(x,y));putchar(‘ ‘); } } return 0; }
100
以上是关于拯救邦德 - 树上递增的主要内容,如果未能解决你的问题,请参考以下文章