UVA 11354 Bond

来源:互联网 发布:手机定时器软件 编辑:程序博客网 时间:2024/06/07 00:05

最小生成树+树链剖分+rmq

#include<cmath>#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define ms(x,y) memset(x,y,sizeof(x))#define rep(i,j,k) for(int i=j;i<=k;i++)#define loop(i,j,k) for (int i=j;i!=-1;i=k[i])#define inone(x) scanf("%d",&x)#define intwo(x,y) scanf("%d%d",&x,&y)#define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z)#define lson x<<1,l,mid#define rson x<<1|1,mid+1,rconst int N = 2e5+ 10;const int INF = 0x7FFFFFFF;int n, m, fa[N], l, r;int x[N], y[N], z[N], a[N];int ft[N], nt[N], u[N], v[N], sz;int dep[N], mx[N], ct[N], top[N];int f[N], g[N], dp[N][20], lg[N];int get(int x) { return x == fa[x] ? x : fa[x] = get(fa[x]); }void AddEdge(int x, int y, int z){u[sz] = y; v[sz] = z; nt[sz] = ft[x]; ft[x] = sz++;u[sz] = x; v[sz] = z; nt[sz] = ft[y]; ft[y] = sz++;}void dfs(int x, int f) {fa[x] = f; mx[x] = 0;ct[x] = 1; dep[x] = dep[f] + 1;loop(i, ft[x], nt){if (u[i] == f) continue;dfs(u[i], x);ct[x] += ct[u[i]];if (ct[u[i]] > ct[mx[x]]) mx[x] = u[i];}}void Dfs(int x, int t){top[x] = !t ? x : top[fa[x]];f[x] = ++sz;if (mx[x]) Dfs(mx[x], 1);loop(i, ft[x], nt){if (u[i] == fa[x]) continue;if (u[i] == mx[x]) { g[f[u[i]]] = v[i]; continue; }Dfs(u[i], 0); g[f[u[i]]] = v[i];}}int rmq(int x, int y){if (x > y) return 0;int r = lg[y - x + 1];return max(dp[x][r], dp[y - (1 << r) + 1][r]);}int query(int x, int y){int res = 0;for (; top[x] != top[y]; x = fa[top[x]]){if (dep[top[x]] < dep[top[y]]) swap(x, y);res = max(res, rmq(f[top[x]], f[x]));}if (dep[x] > dep[y]) swap(x, y);res = max(res, rmq(f[x] + 1, f[y]));return res;}int main(){int flag = 0;while (intwo(n, m) != EOF){if (flag) printf("\n"); else flag = 1;rep(i, 1, n) fa[i] = i, ft[i] = -1;rep(i, 1, m) inthr(x[i], y[i], z[i]), a[i] = i;sort(a + 1, a + m + 1, [](int u, int v) {return z[u] < z[v]; });rep(i, 1, m){int fx = get(x[a[i]]), fy = get(y[a[i]]);if (fx == fy) continue;fa[fx] = fy; AddEdge(x[a[i]], y[a[i]], z[a[i]]);}g[1] = dep[0] = ct[0] = sz = 0;lg[1] = 0; dfs(1, 0); Dfs(1, 0);rep(i, 1, n) dp[i][0] = g[i];rep(i, 2, n) lg[i] = lg[i / 2] + 1;rep(j, 1, 20){rep(i, 1, n){if (i + (1 << j - 1) > n) break;dp[i][j] = max(dp[i][j - 1], dp[i + (1 << j - 1)][j - 1]);}}inone(m);while (m--){intwo(l, r);printf("%d\n", query(l, r));}}return 0;}


0 0
原创粉丝点击