5 1 2 2 4 2 5 1 3 1 2 3 4 5 6 4 2 3 2 1 2 4 2 3 1 3 5 3 2 1 4 4 1 4
3 -1 7HintWe define the illegal situation of different operations: In first operation: if node x and y belong to a same tree, we think it‘s illegal. In second operation: if x = y or x and y not belong to a same tree, we think it‘s illegal. In third operation: if x and y not belong to a same tree, we think it‘s illegal. In fourth operation: if x and y not belong to a same tree, we think it‘s illegal.
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/11/1 10:28:39
File Name :4.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=300300;
struct Node ;
Node *null;
struct Node{
Node *fa,*ch[2];
int Max,val,rev,add;
inline void clear(int _val){
fa=ch[0]=ch[1]=null;
val=Max=_val;
rev=0;
add=0;
}
inline void push_up(){
Max=max(val,max(ch[0]->Max,ch[1]->Max));
}
inline void setc(Node *p,int d){
ch[d]=p;
p->fa=this;
}
inline bool d(){
return fa->ch[1]==this;
}
inline bool isroot(){
return fa==null||fa->ch[0]!=this&&fa->ch[1]!=this;
}
inline void flip(){
if(this==null)return;
swap(ch[0],ch[1]);
rev^=1;
}
inline void update_add(int w){
if(this==null)return;
val+=w;
add+=w;
Max+=w;
}
inline void push_down(){
if(rev){
ch[0]->flip();ch[1]->flip();rev=0;
}
if(add){
ch[0]->update_add(add);
ch[1]->update_add(add);
add=0;
}
}
inline void go(){
if(!isroot())fa->go();
push_down();
}
inline void rot(){
Node *f=fa,*ff=fa->fa;
int c=d(),cc=fa->d();
f->setc(ch[!c],c);
this->setc(f,!c);
if(ff->ch[cc]==f)ff->setc(this,cc);
else this->fa=ff;
f->push_up();
}
inline Node *splay(){
go();
while(!isroot()){
if(!fa->isroot())d()==fa->d()?fa->rot():rot();
rot();
}
push_up();
return this;
}
inline Node *access(){
for(Node *p=this,*q=null;p!=null;q=p,p=p->fa){
p->splay()->setc(q,1);
p->push_up();
}
return splay();
}
inline Node *find_root(){
Node *x;
for(x=access();x->push_down(),x->ch[0]!=null;x=x->ch[0]);
return x;
}
void make_root(){
access()->flip();
}
void cut(){
access();
ch[0]->fa=null;
ch[0]=null;
push_up();
}
void cut(Node *x){
if(this==x||find_root()!=x->find_root())puts("-1");
else{
x->make_root();
cut();
}
}
void link(Node *x){
if(find_root()==x->find_root())puts("-1");
else{
make_root();fa=x;
}
}
};
Node pool[maxn],*tail,*node[maxn];
struct Edge{
int next,to;
}edge[2*maxn];
int head[maxn],tot;
inline void addedge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs(int u,int pre){
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==pre)continue;
node[v]->fa=node[u];
dfs(v,u);
}
}
void ADD(Node *x,Node *y,int w){
x->access();
for(x=null;y!=null;x=y,y=y->fa){
y->splay();
if(y->fa==null){
y->ch[1]->update_add(w);
x->update_add(w);
y->val+=w;
y->push_up();
return;
}
y->setc(x,1);
y->push_up();
}
}
int ask(Node *x,Node *y){
x->access();
for(x=null;y!=null;x=y,y=y->fa){
y->splay();
if(y->fa==null)
return max(y->val,max(y->ch[1]->Max,x->Max));
y->setc(x,1);
y->push_up();
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)head[i]=-1;tot=0;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
tail=pool;
null=tail++;
null->clear(-INF);
for(int i=1;i<=n;i++){
node[i]=tail++;
int v;scanf("%d",&v);
node[i]->clear(v);
}
dfs(1,1);
int m,op,x,y,w;
scanf("%d",&m);
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d%d",&x,&y);
node[x]->link(node[y]);
}
else if(op==2){
scanf("%d%d",&x,&y);
node[y]->cut(node[x]);
}
else if(op==3){
scanf("%d%d%d",&w,&x,&y);
if(node[x]->find_root()!=node[y]->find_root())puts("-1");
else ADD(node[x],node[y],w);
}
else{
scanf("%d%d",&x,&y);
if(node[x]->find_root()!=node[y]->find_root())puts("-1");
else printf("%d\n",ask(node[x],node[y]));
}
}
puts("");
}
return 0;
}原文:http://blog.csdn.net/xianxingwuguan1/article/details/40681011