SPOJ

来源:互联网 发布:人工智能的好处 英文 编辑:程序博客网 时间:2024/06/07 14:35

传送门:SPOJ - QTREE

题意:给出一棵树,和两种操作:

1.把第i条边的权值改成ti。

2.询问a节点到b节点之间的路径中的最大边权值。

思路:树链剖分裸题。

树链剖分学习:点击打开链接

个人理解:树链剖分有点类似于树的dfs序 + 线段树维护,不过是用各种数据结构去维护划分出来的边罢了。

代码:

#include<bits/stdc++.h>#define ll long long#define rank Rank#define pi acos(-1)#define MAXN 10010#define inf 0x3f3f3f3f#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define MID int mid = (l + r) >> 1; using namespace std;typedef pair<int,int>P;struct edge{int u, v, w;}g[MAXN];int fa[MAXN], pos[MAXN], rank[MAXN], son[MAXN], sz[MAXN];int top[MAXN], dep[MAXN];int num[MAXN << 2];int tid;vector<int> mp[MAXN];void init(int n){tid = 0;for(int i = 0; i <= n; i++) mp[i].clear();memset(son, -1, sizeof(int) * (n + 5));memset(num, 0, sizeof(num));}void dfs1(int u){sz[u] = 1;int v;for(int i = 0; i < mp[u].size(); i++){v = mp[u][i];if(v == fa[u]) continue;fa[v] = u; dep[v] = dep[u] + 1;dfs1(v);sz[u] += sz[v];if(son[u] == -1 || sz[v] > sz[son[u]])son[u] = v;}}void dfs2(int u, int head){top[u] = head;pos[u] = ++tid;rank[tid] = u;if(son[u] == -1) return ;dfs2(son[u], head);int v;for(int i = 0; i < mp[u].size(); i++){v = mp[u][i];if(v == son[u] || v == fa[u]) continue;dfs2(v, v);}}void update(int id, int x, int l, int r, int rt){if(l == r){num[rt] = x;return ;}MIDif(id <= mid)update(id, x, lson);if(id > mid)update(id, x, rson);num[rt] = max(num[rt << 1], num[rt << 1 | 1]); }int query(int L, int R, int l, int r, int rt){if(L <= l && r <= R)return num[rt];MID int ans = 0;if(L <= mid) ans = max(ans, query(L, R, lson));if(R > mid) ans = max(ans, query(L, R, rson));return ans;}int get(int u, int v){int f1 = top[u], f2 = top[v], ans = 0;while(f1 != f2){if(dep[f1] < dep[f2])swap(f1, f2), swap(u, v);ans = max(ans, query(pos[f1], pos[u], 1, tid, 1));u = fa[f1], f1 = top[u];}if(u == v) return ans;if(dep[u] > dep[v]) swap(u, v);return max(ans, query(pos[son[u]], pos[v], 1, tid, 1));}char s[50];int main(){int T, n, u, v;cin >> T;while(T--){scanf("%d", &n);init(n);for(int i = 1; i < n; i++){scanf("%d %d %d", &g[i].u, &g[i].v, &g[i].w);mp[g[i].u].push_back(g[i].v);mp[g[i].v].push_back(g[i].u); }fa[1] = dep[1] = 0;dfs1(1);dfs2(1, 1);for(int i = 1; i < n; i++){if(dep[g[i].u] > dep[g[i].v]) swap(g[i].u, g[i].v);update(pos[g[i].v], g[i].w, 1, tid, 1);}while(scanf(" %s", s)){if(s[0] == 'D') break;scanf("%d %d", &u, &v);if(s[0] == 'Q') printf("%d\n", get(u, v));else update(pos[g[u].v], v, 1, tid, 1);}}    return 0;}



原创粉丝点击