您的位置:首页 > 其它

在此为LCT开一个永久的坑

2016-07-23 10:13 225 查看

其实我连splay都还不怎么会。

今天先抄了黄学长的bzoj2049,以后一定要把它理解了。

写LCT怎么能不%数据结构大神yeweining呢?%%%chrysanthemums  %%%切掉大森林的全ZJ唯一一人

#include<cstdio>
#include<algorithm>
#define inf 2e9
#define N 500020
using namespace std;
int u,v,a,b,n,m,rev
,ans=inf,stack
,val
,fa
,maxn
,f
,ch
[2];
struct wxx{int u,v,a,b;}edge
;
bool cmp(wxx a,wxx b){if(a.a==b.a)return a.b<b.b;return a.a<b.a;}
int find(int x){if(fa[x]!=x)fa[x]=find(fa[x]);return fa[x];}
bool isrt(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
int get(int x){return ch[f[x]][1]==x;}
void update(int x){
if(x){
maxn[x]=x;
if(ch[x][0]){
if(val[maxn[ch[x][0]]]>val[maxn[x]])maxn[x]=maxn[ch[x][0]];
}
if(ch[x][1]){
if(val[maxn[ch[x][1]]]>val[maxn[x]])maxn[x]=maxn[ch[x][1]];
}
}
}
void rotate(int x){
int yl=f[x],yf=f[yl],you=get(x);
if(isrt(yl)==0)ch[yf][ch[yf][1]==yl]=x;
f[x]=yf;
ch[yl][you]=ch[x][you^1];f[ch[yl][you]]=yl;
ch[x][you^1]=yl;f[yl]=x;
update(yl);update(x);
}
void pushdown(int x){
if(x&&rev[x]){
swap(ch[x][0],ch[x][1]);
if(ch[x][0])rev[ch[x][0]]^=1;
if(ch[x][1])rev[ch[x][1]]^=1;
rev[x]=0;
}
}
void splay(int x){
int top=0;stack[++top]=x;
for(int i=x;!isrt(i);i=f[i])stack[++top]=f[i];
for(int i=top;i>=1;i--)pushdown(stack[i]);

for(int ff;isrt(x)==0;rotate(x)){
ff=f[x];
if(isrt(ff)==0)
if(get(x)==get(ff))rotate(ff);else rotate(x);
}
}
void access(int x){
int t=0;
for (;x;t=x,x=f[x]){
splay(x);
ch[x][1]=t;
update(x);
}

}
void reverse(int x){
access(x);splay(x);rev[x]^=1;
}
void link(int x,int y){
reverse(x);f[x]=y;splay(x);
}
void cut(int x,int y){
reverse(x);access(y);splay(y);
ch[y][0]=f[x]=0;
}
int query(int x,int y){
reverse(x);access(y);splay(y);
return maxn[y];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&edge[i].u,&edge[i].v,&edge[i].a,&edge[i].b);
}
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=m;i++)val[n+i]=edge[i].b;
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
int fx=find(edge[i].u),fy=find(edge[i].v);
if(fx!=fy){
link(edge[i].u,n+i);
link(n+i,edge[i].v);
fa[fx]=fy;
} else{
int k=query(edge[i].u,edge[i].v);
if(val[k]>edge[i].b){
cut(edge[k-n].u,k);
cut(k,edge[k-n].v);
link(edge[i].u,n+i);
link(n+i,edge[i].v);
}}
if(find(1)==find(n)){
int k=query(1,n);
ans=min(ans,edge[i].a+val[k]);
}

}
if(ans==inf)ans=-1;printf("%d\n",ans);
}
bzoj3669

 

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