您的位置:首页 > 其它

bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)

2016-03-26 18:35 387 查看
【深坑勿入】

【给个链接】

  /article/2348245.html

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=b;a<=c;a++)
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
using namespace std;

typedef long long ll;
typedef unsigned int ul;
const int N = 4e5+10;

ll read() {
char c=getchar();
ll f=1,x=0;
while(!isdigit(c)) {
if(c=='-') f=-1; c=getchar();
}
while(isdigit(c))
x=x*10+c-'0',c=getchar();
return x*f;
}

struct Edge {
int u,v,w;
bool operator < (const Edge& rhs) const {
return u<rhs.u||(u==rhs.u&&v<rhs.v);
}
}e[N<<2];

namespace LCT {

struct Node {
Node *ch[2],*fa;
int rev,id,maxe;
Node() ;
void reverse() {
rev^=1;
swap(ch[0],ch[1]);
}
void up_push() {
if(fa->ch[0]==this||fa->ch[1]==this)
fa->up_push();
if(rev) {
ch[0]->reverse();
ch[1]->reverse();
rev=0;
}
}
void maintain() {
int _max=-1;
if(e[ch[0]->maxe].w>_max)
_max=e[ch[0]->maxe].w,maxe=ch[0]->maxe;
if(e[ch[1]->maxe].w>_max)
_max=e[ch[1]->maxe].w,maxe=ch[1]->maxe;
if(e[id].w>_max) maxe=id;
}
} *null=new Node,T
,E[N<<2];
Node::Node() {
id=maxe=rev=0;
fa=ch[0]=ch[1]=null;
}

void rot(Node* o,int d) {
Node *p=o->fa;
p->ch[d]=o->ch[d^1];
o->ch[d^1]->fa=p;
o->ch[d^1]=p;
o->fa=p->fa;
if(p==p->fa->ch[0])
p->fa->ch[0]=o;
else if(p==p->fa->ch[1])
p->fa->ch[1]=o;
p->fa=o;
p->maintain();
}
void splay(Node *o) {
o->up_push();
Node *nf,*nff;
while(o->fa->ch[0]==o||o->fa->ch[1]==o) {
nf=o->fa,nff=nf->fa;
if(o==nf->ch[0]) {
if(nf==nff->ch[0]) rot(nf,0);
rot(o,0);
} else {
if(nf==nf->ch[1]) rot(nf,1);
rot(o,1);
}
}
o->maintain();
}
void Access(Node* o) {
Node *son=null;
while(o!=null) {
splay(o);
o->ch[1]=son;
o->maintain();
son=o; o=o->fa;
}
}
void evert(Node* o) {
Access(o);
splay(o);
o->reverse();
}
void Link(Node* u,Node* v) {
evert(u);
u->fa=v;
}
void Cut(Node* u,Node* v) {
evert(u);
Access(v); splay(v);
u->fa=v->ch[0]=null;
v->maintain();
}
Node* find(Node* o) {
while(o->fa!=null) o=o->fa;
return o;
}

}
using namespace LCT;

int n,m,q,flag
,ans
;

struct Q { int op,x,y;
}que
;

int query(Node* u,Node* v)
{
if(find(u)!=find(v)) return 0;
evert(u);
Access(v),splay(v);
return v->maxe;
}
void insert(Node* u,Node* v,int id)
{
if(find(u)==find(v)) {
int maxe=query(u,v);
if(e[maxe].w<=e[id].w) return ;
Cut(&E[maxe],&T[e[maxe].u]);
Cut(&E[maxe],&T[e[maxe].v]);
}
Link(&E[id],u);
Link(&E[id],v);
}
int search(Edge x)
{
int l=1,r=m,mid;
while(l<=r) {
mid=l+r>>1;
if((!(e[mid]<x))&&(!(x<e[mid]))) return mid;
if(x<e[mid]) r=mid-1;
else l=mid+1;
}
return 0;
}

int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
n=read(),m=read(),q=read();
FOR(i,0,m) E[i].maxe=E[i].id=i;
FOR(i,1,m) {
e[i].u=read(),e[i].v=read(),e[i].w=read();
if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
}
e[0].w=0;
sort(e+1,e+m+1);
FOR(i,1,q) {
que[i].op=read(),que[i].x=read(),que[i].y=read();
if(que[i].x>que[i].y) swap(que[i].x,que[i].y);
if(que[i].op==2) {
int x=search((Edge){que[i].x,que[i].y,0});
if(x==0) puts("error");
flag[x]=1;
}
}
FOR(i,1,m) if(!flag[i]) {
insert(&T[e[i].u],&T[e[i].v],i);
}
for(int i=q;i;i--) {
if(que[i].op==2) {
int x=search((Edge){que[i].x,que[i].y,0});
insert(&T[e[x].u],&T[e[x].v],x);
} else {
ans[i]=e[query(&T[que[i].x],&T[que[i].y])].w;
}
}
FOR(i,1,q) if(que[i].op==1)
printf("%d\n",ans[i]);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: