【BZOJ】【3669】【NOI2014】魔法森林

LCT动态维护MST

  LCT动态维护MST

  我们可以枚举a,然后找从1到n的一条路径使得:这条路径上的b的最大值最小。这个路径肯定在MST上……所以枚举一遍所有的边,动态维护一个关于b值的MST即可。

调了半天没出解的原因:

  rotate写错了……l=c[y][1]==x 我写成了 l=c[z][1]==y sigh……

 /**************************************************************
Problem: 3669
User: Tunix
Language: C++
Result: Accepted
Time:4752 ms
Memory:7896 kb
****************************************************************/ //BZOJ 3669
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*=sign;
}
const int N=,INF=~0u>>;
/******************tamplate*********************/
struct LCT{
int c[N][],fa[N],v[N],mx[N];
bool rev[N];
int st[N],top;
#define L c[x][0]
#define R c[x][1]
void Push_up(int x){
mx[x]=x;
if (v[mx[L]]>v[mx[x]]) mx[x]=mx[L];
if (v[mx[R]]>v[mx[x]]) mx[x]=mx[R];
}
void Push_down(int x){
if (rev[x]) rev[x]=,rev[L]^=,rev[R]^=,swap(L,R);
}
bool not_root(int x){
return c[fa[x]][]==x || c[fa[x]][]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y],l=c[y][]==x,r=l^;
if (not_root(y)) c[z][c[z][]==y]=x;
fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
Push_up(y);
}
void preview(int x){
top=; st[++top]=x;
for(;not_root(x);x=fa[x])
st[++top]=fa[x];
D(i,top,) Push_down(st[i]);
}
void splay(int x,int y=){
for(preview(x);not_root(x);rotate(x))
if (not_root(y=fa[x]))
rotate( c[y][]==x^c[fa[y]][]==y ? x : y);
Push_up(x);
}
void access(int x,int y=){
for(;x;splay(x),c[x][]=y,y=x,x=fa[x]);
}
void makeroot(int x){
access(x); splay(x); rev[x]^=;
}
void link(int x,int y){
makeroot(x);fa[x]=y;
}
void cut(int x,int y){
makeroot(x);access(y);splay(y);
if (c[y][]==x) c[y][]=fa[x]=;
}
int query(int x,int y){
makeroot(x),access(y),splay(y);
return mx[y];
}
}t;
/*********************LCT***********************/
struct edge{
int x,y,a,b;
bool operator < (const edge &e) const {
return a < e.a;
}
}e[N];
int fa[N];
int find(int x){return fa[x]==x ? x : fa[x]=find(fa[x]);} int main(){
#ifndef ONLINE_JUDGE
freopen("3669.in","r",stdin);
freopen("3669.out","w",stdout);
#endif
int n,m;
n=getint(); m=getint();
F(i,,m){
e[i].x=getint(); e[i].y=getint();
e[i].a=getint(); e[i].b=getint();
}
sort(e+,e+m+);
F(i,,m){
t.v[n+i]=e[i].b;
t.mx[n+i]=n+i;
}
F(i,,n) fa[i]=i; int ans=INF;
F(i,,m){
int f1=find(e[i].x),f2=find(e[i].y);
if (f1!=f2){
fa[f1]=f2;
t.link(e[i].x,n+i); t.link(e[i].y,n+i);
}
else{
int tmp=t.query(e[i].x,e[i].y);
if (e[i].b<t.v[tmp]){//这一步即可略去自环
t.cut(e[tmp-n].x,tmp); t.cut(e[tmp-n].y,tmp);
t.link(e[i].x,i+n); t.link(e[i].y,i+n);
}
}
f1=find(); f2=find(n);
if (f1==f2)
ans=min(ans,e[i].a+t.v[t.query(,n)]);
}
printf("%d\n",ans==INF ? - : ans);
return ;
}
上一篇:httpd的压力测试工具


下一篇:hp-pa安装oracle和bash