Qtree第一种解法,采用动态树。详情参考杨哲《Qtree解法的一些研究》。数据结构用Splay Tree。要特别注意理解Link-Cut Tree,尤其是他的Access操作。
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
#define MAXN 10005
int father[MAXN];
struct ANode
{
int v;
int w;
ANode * next;
ANode(int _v,int _w,ANode * _next)
{
v = _v;
w = _w;
next = _next;
}
}*adj[MAXN];
struct Node
{
Node * father;
Node * ch[2];
bool root;//是不是所在Splay Tree的根节点
int cost;//此节点到父节点的权值
int maxcost;//以此节点为根的子树的cost的最大值
}tree[MAXN],*null,Tnull;
void init(Node * p)
{
p->ch[0] = p->ch[1] = p->father = null;
p->maxcost = p->cost = 0;
p->root = true;
}
void bfs()
{
queue<int> q;
q.push(1);
memset(father,-1,sizeof(father));
father[1] = 0;
while(q.size())
{
int u = q.front();
q.pop();
for(ANode * p = adj[u];p;p = p->next)
{
if(father[p->v] == -1)
{
father[p->v] = u;
tree[p->v].father = tree + u;
tree[p->v].cost = tree[p->v].maxcost = p->w;
q.push(p->v);
}
}
}
}
void push_up(Node * p)
{
p->maxcost = max(max(p->ch[0]->maxcost,p->ch[1]->maxcost),p->cost);
}
void rotate(Node * x,int c)
{
Node * y = x->father;
y->ch[!c] = x->ch[c];
if(x->ch[c]!=null)
{
x->ch[c]->father = y;
}
x->father = y->father;
if(y->father!=null)
{
if(y->father->ch[0] == y)
{
y->father->ch[0] = x;
}
else if(y->father->ch[1] == y)//一定要用Else If,如果直接用Else会出现错误,因为树本身可能不是二叉树,虽然生成的Splay Tree是
{
y->father->ch[1] = x;
}
}
x->ch[c] = y;
y->father = x;
push_up(y);
//push_up(x);
if(y->root)
{
x->root = true;
y->root = false;
}
}
void splay(Node * p)
{
if(p == null)
{
return;
}
for(;!p->root;)
{
if(p->father->root)
{
if(p->father->ch[0] == p)
{
rotate(p,1);
}
else
{
rotate(p,0);
}
}
else
{
Node * y = p->father;
Node * z = y->father;
if(z->ch[0] == y)
{
if(y->ch[0] == p)//一字形旋转
{
rotate(y,1);
rotate(p,1);
}
else
{
rotate(p,0);
rotate(p,1);
}
}
else
{
if(y->ch[1] == p)
{
rotate(y,0);
rotate(p,0);
}
else
{
rotate(p,1);
rotate(p,0);
}
}
}
}
push_up(p);
}
void access(Node * u,int flag)
{
Node * v = null;
while(u!=null)
{
splay(u);
if(flag == 2)
{
if(u->father == null)
{
printf("%d\n",max(u->ch[1]->maxcost,v->maxcost));
}
}
u->ch[1]->root = true;
u->ch[1] = v;
v->root = false;
push_up(u);
v = u;
u = u->father;
}
}
void query(int u,int v)
{
access(tree + u,1);
access(tree + v,2);
}
void change(int u,int cost)
{
access(tree + u,1);
splay(tree + u);
tree[u].cost = cost;
push_up(tree + u);
}
vector<pair<int,int> > edge;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
int N;
int a,b,c;
char cmd[20];
scanf("%d",&T);
null = &Tnull;
init(null);
while(T--)
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
adj[i] = NULL;
init(&tree[i]);
}
edge.clear();
for(int i=0;i<N-1;i++)
{
scanf("%d%d%d",&a,&b,&c);
adj[a] = new ANode(b,c,adj[a]);
adj[b] = new ANode(a,c,adj[b]);
edge.push_back(make_pair(a,b));
}
bfs();
while(1)
{
scanf("%s",cmd);
if(strcmp(cmd,"QUERY") == 0)
{
scanf("%d%d",&a,&b);
query(a,b);
}
if(strcmp(cmd,"CHANGE") == 0)
{
scanf("%d%d",&a,&b);
a--;
int u = edge[a].first;
int v = edge[a].second;
if(father[u] == v)
{
change(u,b);
}
else if(father[v] == u)
{
change(v,b);
}
}
if(strcmp(cmd,"DONE")==0)
{
break;
}
}
}
return 0;
}
参考资料: http://wenku.baidu.com/view/75906f160b4e767f5acfcedb.html