[UOJ 3]【NOI2014】魔法森林:LCT
来源:互联网 发布:老板的红颜知已 编辑:程序博客网 时间:2024/06/06 04:51
点击这里查看原题
将所有路径按a升序排序,用LCT维护路径上最大的b,将边权化为点权,如果加入一条边x,其两端点分别为u,v,那么将u与i+x连边,v与i+x连边。
如果(u,v)路径最大的b值大于当前边的b,那么删去b最大的边。
注意:access操作中必须pushup,因为这个调了好久
/*User:SmallLanguage:C++Problem No.:3*/#include<bits/stdc++.h>#define ll long long#define inf 99999999using namespace std;const int M=200005;int n,m,pre[M],fa[M],ch[M][2],val[M],mx[M],stk[M],ans=inf;bool rev[M];struct edge{ int u,v,a,b; bool operator<(const edge &y)const{ return a<y.a; }}e[M];bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}bool get(int x){ return ch[fa[x]][1]==x;}void pushup(int rt){ int &l=ch[rt][0],&r=ch[rt][1]; mx[rt]=rt; if(val[mx[l]]>val[mx[rt]]) mx[rt]=mx[l]; if(val[mx[r]]>val[mx[rt]]) mx[rt]=mx[r];}void pushdown(int rt){ int &l=ch[rt][0],&r=ch[rt][1]; if(rev[rt]){ rev[rt]^=1; rev[l]^=1; rev[r]^=1; swap(l,r); }}void rotate(int x){ int y=fa[x],z=fa[y],side=get(x); if(!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; ch[y][side]=ch[x][side^1]; fa[ch[y][side]]=y; ch[x][side^1]=y; fa[y]=x; pushup(y); pushup(x); }void splay(int x){ int tp=0; stk[++tp]=x; for(int u=x;!isroot(u);u=fa[u]) stk[++tp]=fa[u]; while(tp) pushdown(stk[tp--]); while(!isroot(x)){ int y=fa[x]; if(!isroot(y)) rotate(get(x)==get(y)?y:x); rotate(x); }}void access(int x){ int t=0; for(int t=0;x;t=x,x=fa[x]){ splay(x); ch[x][1]=t; pushup(x); }}void makeroot(int x){ access(x); splay(x); rev[x]^=1;}void link(int x,int y){ makeroot(x); fa[x]=y; splay(x);}void cut(int x,int y){ makeroot(x); access(y); splay(y); fa[x]=ch[y][0]=0;}int query(int x,int y){ makeroot(x); access(y); splay(y); return mx[y];}int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]);}int main(){ freopen("data.in","r",stdin);// ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].a>>e[i].b; sort(e+1,e+m+1); for(int i=1;i<=m;i++){ int u=e[i].u,v=e[i].v; if(find(u)==find(v)){ int t=query(u,v); if(val[t]<=e[i].b) continue; cut(t,e[t-n].u); cut(t,e[t-n].v); } else pre[find(u)]=find(v); val[i+n]=e[i].b; mx[i+n]=i+n; link(u,i+n); link(v,i+n); if(find(1)==find(n)) ans=min(ans,e[i].a+val[query(1,n)]); } if(ans==inf) ans=-1; cout<<ans<<endl; return 0;}
阅读全文
0 0
- [BZOJ3669][UOJ#3][Noi2014][LCT]魔法森林
- [UOJ 3]【NOI2014】魔法森林:LCT
- UOJ #3(【NOI2014】魔法森林-LCT区间最值)
- NOI2014-魔法森林(LCT)
- [NOI2014魔法森林]LCT
- NOI2014魔法森林--LCT
- uoj 魔法森林--LCT
- bzoj3669: [Noi2014]魔法森林 LCT
- [BZOJ3669][Noi2014]魔法森林 && LCT
- 3669: [Noi2014]魔法森林 LCT
- 【bzoj3669】[Noi2014]魔法森林 LCT
- 【jzoj3754】【NOI2014】【魔法森林】【lct】
- 【BZOJ3669】【NOI2014】魔法森林 LCT
- 【BZOJ】【P3669】【NOI2014】【魔法森林】【题解】【LCT】
- BZOJ 3669 [Noi2014]魔法森林 LCT
- 【LCT】BZOJ 3669: [Noi2014]魔法森林
- BZOJ_P3669&Codevs_P3314 [NOI2014]魔法森林(LCT+Kruskal)
- bzoj 3669 NOI2014 魔法森林 [LCT]
- Myeclipse如何自动创建hibernate
- css3简介
- Libevent源码分析-----event_signal_map
- 【TopDesk】新项目:总起+目录篇
- Oracle和Mysql数据库的分页怎么写?
- [UOJ 3]【NOI2014】魔法森林:LCT
- Zend Studio 12.0.1 修改默认的项目路径
- 设计模式之策略模式
- CSRF 攻击的应对之道
- jQuery常用方法
- 数字相关知识
- 【整理】单元测试与功能测试的区别
- Libevent源码分析-----配置event_base
- 292. Nim Game