您的位置:首页 > 其它

【POJ】3237 Tree

2012-08-23 21:40 295 查看
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
#define MAXN 100010
#define MAXM 200010
#define oo 0x7FFFFFFF
using namespace std;
bool vis[MAXN];
int first[MAXN], next[MAXM], v[MAXM], cost[MAXM], e;
struct LCT {
bool neg[MAXN];
int maxi[MAXN], mini[MAXN];
int bef[MAXN], belong[MAXN];
int next[MAXN][2], pre[MAXN], key[MAXN];
void Init() {
memset(next, 0, sizeof(next));
memset(pre, 0, sizeof(pre));
memset(neg, false, sizeof(neg));
maxi[0] = -oo;
mini[0] = oo;
}
inline void PushUp(int x) {
maxi[x] = key[x];
if (next[x][0])
maxi[x] = max(maxi[x], maxi[next[x][0]]);
if (next[x][1])
maxi[x] = max(maxi[x], maxi[next[x][1]]);
mini[x] = key[x];
if (next[x][0])
mini[x] = min(mini[x], mini[next[x][0]]);
if (next[x][1])
mini[x] = min(mini[x], mini[next[x][1]]);
}
inline void Not(int x) {
if (x) {
neg[x] ^= true;
swap(maxi[x], mini[x]);
key[x] = -key[x];
maxi[x] = -maxi[x];
mini[x] = -mini[x];
}
}
inline void PushDown(int x) {
if (neg[x]) {
Not(next[x][0]);
Not(next[x][1]);
neg[x] = false;
}
}
void Rotate(int x, int kind) {
int y, z;
y = pre[x];
z = pre[y];
PushDown(y);
PushDown(x);
next[y][!kind] = next[x][kind];
pre[next[x][kind]] = y;
next[z][next[z][1] == y] = x;
pre[x] = z;
next[x][kind] = y;
pre[y] = x;
PushUp(y);
}
void Splay(int x) {
int rt;
for (rt = x; pre[rt]; rt = pre[rt])
;
if (rt != x) {
bef[x] = bef[rt];
bef[rt] = 0;
PushDown(x);
while (pre[x]) {
if (next[pre[x]][0] == x)
Rotate(x, 1);
else
Rotate(x, 0);
}
PushUp(x);
}
}
void Access(int x) {
int father;
for (father = 0; x; x = bef[x]) {
Splay(x);
PushDown(x);
pre[next[x][1]] = 0;
bef[next[x][1]] = x;
next[x][1] = father;
pre[father] = x;
bef[father] = 0;
father = x;
PushUp(x);
}
}
void Change(int x, int y) {
int t;
t = belong[x - 1];
Splay(t);
key[t] = y;
}
void Negate(int x, int y) {
Access(y);
for (y = 0; x; x = bef[x]) {
Splay(x);
if (!bef[x]) {
Not(y);
Not(next[x][1]);
return;
}
PushDown(x);
pre[next[x][1]] = 0;
bef[next[x][1]] = x;
next[x][1] = y;
pre[y] = x;
bef[y] = 0;
y = x;
PushUp(x);
}
}
int Query(int x, int y) {
Access(y);
for (y = 0; x; x = bef[x]) {
Splay(x);
if (!bef[x])
return max(maxi[y], maxi[next[x][1]]);
PushDown(x);
pre[next[x][1]] = 0;
bef[next[x][1]] = x;
next[x][1] = y;
pre[y] = x;
bef[y] = 0;
y = x;
PushUp(x);
}
return 0;
}
} lct;
int INT() {
char ch;
int res;
bool neg;
while (ch = getchar(), !isdigit(ch) && ch != '-')
;
if (ch == '-') {
res = 0;
neg = true;
} else {
res = ch - '0';
neg = false;
}
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - '0';
return neg ? -res : res;
}
char CHAR() {
char ch, res;
while (res = getchar(), !isalpha(res))
;
while (ch = getchar(), isalpha(ch))
;
return res;
}
inline void AddEdge(int x, int y, int val) {
v[e] = y;
cost[e] = val;
next[e] = first[x];
first[x] = e++;
}
void BFS(int x) {
int i, y;
queue<int> q;
memset(vis, false, sizeof(vis));
vis[x] = true;
q.push(x);
while (!q.empty()) {
x = q.front();
q.pop();
for (i = first[x]; i != -1; i = next[i]) {
y = v[i];
if (!vis[y]) {
lct.bef[y] = x;
lct.key[y] = cost[i];
lct.belong[i >> 1] = y;
vis[y] = true;
q.push(y);
}
}
}
}
int main() {
int c, i;
char ch;
int n, x, y, val;
c = INT();
while (c--) {
n = INT();
lct.Init();
memset(first, -1, sizeof(first));
for (e = 0, i = 1; i < n; i++) {
x = INT(), y = INT(), val = INT();
AddEdge(x, y, val);
AddEdge(y, x, val);
}
BFS(1);
while (ch = CHAR(), ch != 'D') {
x = INT(), y = INT();
if (ch == 'Q')
printf("%d\n", lct.Query(x, y));
else if (ch == 'C')
lct.Change(x, y);
else
lct.Negate(x, y);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: