您的位置:首页 > 其它

【BZOJ】【P2594】【Wc2006】【水管局长数据加强版】【题解】【LCT】

2014-12-20 11:36 288 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2594

其实以前都是背模板……彻底的学习一下LCT

Code:

#include<bits/stdc++.h>
#define V(x) (LCT::pool+x)
#define E(x) (LCT::pool+n+x)
using namespace std;
const int maxn=100010;
const int maxm=1000010;
int n,m,q,anss[maxn];
struct edge{int u,v,w,f,id;bool operator<(const edge o)const{return w<o.w;}}edges[maxm],_edges[maxm];
struct qes{int op,x,y;}Q[maxn];
namespace LCT{
struct node{
int rev,val;
node *c[2],*p,*mx;
void makerev(){rev^=1;swap(c[0],c[1]);}
void pd(){if(rev){rev=0;c[0]->makerev();c[1]->makerev();}}
void rz(){
mx=this;
if(mx->val<c[0]->mx->val)mx=c[0]->mx;
if(mx->val<c[1]->mx->val)mx=c[1]->mx;
}
void sets(node *x,int d){pd();(c[d]=x)->p=this;rz();}
bool d(){return p->c[1]==this;}
bool rt(){return p->c[0]!=this&&p->c[1]!=this;}
}*null,pool[maxn+maxm];
node *newnode(int _val=0){
static node *x=pool;x->rev=0;x->val=_val;
x->c[0]=x->c[1]=x->p=null;x->mx=x;
return x++;
}
void init(){
null=newnode();
null->c[0]=null->c[1]=null->p=null->mx=null;
for(int i=1;i<=n;i++)newnode();
for(int i=1;i<=m;i++)newnode(edges[i].w);
}
void rot(node *x){
node *y=x->p;if(!y->rt())y->p->pd();
y->pd();x->pd();int d=x->d();
y->sets(x->c[!d],d);
if(y->rt())x->p=y->p;
else y->p->sets(x,y->d());
x->sets(y,!d);
}
void splay(node *x){
for(;!x->rt();rot(x))if(x->p->rt());
else if(x->d()==x->p->d())rot(x->p);
else rot(x);
}
node *access(node *x){
node *y=null;
for(;x!=null;x=x->p)splay(x),x->sets(y,1),y=x;
return y;
}
void makert(node *x){
access(x)->makerev();splay(x);
}
void link(node *x,node *y){
makert(x);
x->p=y;
access(x);
}
void cut(node *x,node *y){
makert(x);access(y);splay(y);
y->c[0]=x->p=null;y->rz();
}
node *Qmax(node *x,node *y){
makert(x);access(y);splay(y);
return y->mx;
}
}
int getint(){
int res=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))res=res*10+c-'0',c=getchar();
return res;
}typedef pair<int,int> pi;map<pi,int>M;
int fa[maxn];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
edges[i].u=getint(),edges[i].v=getint(),
edges[i].w=getint(),edges[i].f=1,edges[i].id=i;
if(edges[i].u>edges[i].v)swap(edges[i].u,edges[i].v);
M[pi(edges[i].u,edges[i].v)]=i;
}LCT::init();
for(int i=1;i<=q;i++){
Q[i].op=getint();Q[i].x=getint();Q[i].y=getint();
if(Q[i].x>Q[i].y)swap(Q[i].x,Q[i].y);
if(Q[i].op==2)edges[M[pi(Q[i].x,Q[i].y)]].f=0;
}copy(edges+1,edges+1+m,_edges+1);
sort(_edges+1,_edges+1+m);
for(int i=1,k=0;i<=m&&k<n;i++){
int u=_edges[i].u,v=_edges[i].v;
if(find(u)==find(v)||!_edges[i].f)continue;
fa[find(u)]=find(v);k++;
LCT::link(V(u),E(_edges[i].id));
LCT::link(E(_edges[i].id),V(v));
}
for(int i=q;i;i--){
int op=Q[i].op,x=Q[i].x,y=Q[i].y;
if(op==1){
anss[++anss[0]]=LCT::Qmax(V(x),V(y))->val;
}else{
int id=M[pi(x,y)];
LCT::node *p=LCT::Qmax(V(x),V(y));
if(p->val>edges[id].w){
int eid=p-LCT::pool-n;
LCT::cut(V(edges[eid].u),E(eid));
LCT::cut(E(eid),V(edges[eid].v));
LCT::link(V(x),E(id));
LCT::link(E(id),V(y));
}
}
}for(int i=anss[0];i;i--)printf("%d\n",anss[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj