LCT练手好题啊。

SPFA的做♂FA是把边按照a排序,然后加一条权值为b的边跑SPFA,不断更新答案。很好的做♂FA,但复杂度无♂FA保证。

LCT的做♂FA类似,也是把边按照a排序,然后也是加一条权值为b的边,动态维护最小生成树。

然后赋边权的方♂FA是新建一个点表示边,原来点的权值为0,边的权值还是边的权值,剩下的都一样辣。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
typedef int mainint;
#define int long long
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=100001,maxm=100001;
namespace LCT{
int ch[maxn][2],fa[maxn],w[maxn],mx[maxn],A[maxn],B[maxn];bool rev[maxn];
int index;
il vd down(const int&x){if(rev[x])std::swap(ch[x][0],ch[x][1]),rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,rev[x]=0;}
il vd upd(const int&x){
mx[x]=x;
if(w[mx[x]]<w[mx[ch[x][0]]])mx[x]=mx[ch[x][0]];
if(w[mx[x]]<w[mx[ch[x][1]]])mx[x]=mx[ch[x][1]];
}
il bool isrt(const int&x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
il vd rotate(const int&x){
sta int y,z,o;y=fa[x],z=fa[y],o=x==ch[y][1];
if(!isrt(y))ch[z][y==ch[z][1]]=x;fa[x]=z;
ch[y][o]=ch[x][!o];fa[ch[x][!o]]=y;
fa[y]=x;ch[x][!o]=y;
upd(y);
}
il vd splay(const int&x){
sta int stk[maxn],top;stk[top=1]=x;
for(rg int i=x;!isrt(i);i=fa[i])stk[++top]=fa[i];
while(top)down(stk[top--]);
for(rg int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
if(!isrt(y))rotate(((x==ch[y][1])==(y==ch[z][1]))?y:x);
upd(x);
}
il vd access(int x){for(rg int y=0;x;x=fa[y=x])splay(x),ch[x][1]=y,upd(x);}
il vd makert(const int&x){access(x),splay(x);rev[x]^=1;}
il int find(int x){access(x),splay(x);while(ch[x][0])x=ch[x][0];return x;}
il vd split(const int&x,const int&y){makert(x);access(y),splay(y);}
il vd _link(const int&x,const int&y){makert(x),fa[x]=y;}
il vd cut(const int&x,const int&y){split(x,y);fa[x]=ch[y][0]=0;}
il vd link(const int&x,const int&y,const int&k){
if(find(x)^find(y)){w[++index]=k,_link(A[index]=x,index),_link(B[index]=y,index);return;}
split(x,y);
sta int s;s=mx[y];
if(w[s]<=k)return;
cut(s,A[s]),cut(s,B[s]);
w[s]=k,_link(A[s]=x,s),_link(B[s]=y,s);
}
il int query(int x,int y){
if(find(x)^find(y))return 1e18;
split(x,y);return w[mx[y]];
}
}
struct edge{int x,y,a,b;}E[maxm];
bool operator <(const edge&a,const edge&b){return a.a<b.a;}
mainint main(){
freopen("magicalforest.in","r",stdin);
freopen("magicalforest.out","w",stdout);
int n=gi(),m=gi();
for(rg int i=1;i<=m;++i)E[i].x=gi(),E[i].y=gi(),E[i].a=gi(),E[i].b=gi();
std::sort(E+1,E+m+1);
int ans=1e18;
LCT::index=n;
for(rg int i=1;i<=m;++i)LCT::link(E[i].x,E[i].y,E[i].b),ans=std::min(ans,E[i].a+LCT::query(1,n));
if(ans==1e18)ans=-1;printf("%lld\n",ans);
return 0;
}

cogs1685 【NOI2014】魔法森林 Link-Cut Tree的更多相关文章

  1. [NOI2014] 魔法森林 - Link Cut Tree

    [NOI2014] 魔法森林 Description 给定一张图,每条边 \(i\) 的权为 \((a_i,b_i)\), 求一条 \(1 \sim n\) 路径,最小化 \(\max_{i\in P ...

  2. BZOJ 3669 [Noi2014]魔法森林 ——SPFA / Link-Cut Tree

    [题目分析] 大意就是有一张图,边权有两个值,ai和bi 找到一条路径,使得路径上的max(ai)+max(bi)最小. 遇到有两个权值或者多个权值的时候,如果他们互相影响,试着用分块搞一搞. 如果互 ...

  3. 【BZOJ3669】【Noi2014】魔法森林(Link-Cut Tree)

    [BZOJ3669][Noi2014]魔法森林(Link-Cut Tree) 题面 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n ...

  4. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  5. Link Cut Tree 总结

    Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...

  6. 学习笔记:Link Cut Tree

    模板题 原理 类似树链剖分对重儿子/长儿子剖分,Link Cut Tree 也做的是类似的链剖分. 每个节点选出 \(0 / 1\) 个儿子作为实儿子,剩下是虚儿子.对应的边是实边/虚边,虚实时可以进 ...

  7. BZOJ_3669_[Noi2014]魔法森林_LCT

    BZOJ_3669_[Noi2014]魔法森林_LCT Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节 ...

  8. bzoj 3669: [Noi2014]魔法森林 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec  ...

  9. 「luogu2387」[NOI2014] 魔法森林

    「luogu2387」[NOI2014] 魔法森林 题目大意 \(n\) 个点 \(m\) 条边的无向图,每条边上有两个权值 \(a,b\),求从 \(1\) 节点到 \(n\) 节点 \(max\{ ...

  10. P2387 [NOI2014]魔法森林(LCT)

    P2387 [NOI2014]魔法森林 LCT边权维护经典题 咋维护呢?边化为点,边权变点权. 本题中我们把边对关键字A进行排序,动态维护关键字B的最小生成树 加边后出现环咋办? splay维护最大边 ...

随机推荐

  1. pycharm something

    e1:使用的版本2016.3 发现无法执行py程序,执行菜单为灰色.选择py为2.7. e2:使用过jython可以运行,但是语法有问题str.formate无法执行

  2. Python学习---IO的异步[asyncio模块(no-http)]

    Asyncio进行异步IO请求操作: 1. @asyncio.coroutine  装饰任务函数 2. 函数内配合yield from 和装饰器@asyncio.coroutine 配合使用[固定格式 ...

  3. Coursera-AndrewNg(吴恩达)机器学习笔记——第二周编程作业(线性回归)

    一.准备工作 从网站上将编程作业要求下载解压后,在Octave中使用cd命令将搜索目录移动到编程作业所在目录,然后使用ls命令检查是否移动正确.如: 提交作业:提交时候需要使用自己的登录邮箱和提交令牌 ...

  4. asp.net core中DockerFile文件中的COPY

    今天在ubuntu系统中使用docker部署asp.net core时遇到了一个问题,docker build 的时候总会在最后一步提示 lstat obj/Docker/publish: no su ...

  5. Atom 绝赞插件

    文件图标: file-icons 根据不同文件后缀名显示不同类型图标 标签栏根据不同文件格式显示色彩: filetype-color 在标签栏不同格式文件显示不同的颜色的标题,支持二度设置. 小地图: ...

  6. 拟牛顿 DFP matlab

    function sevnn x=[1,0]'; [x,val]=dfp('fun','gfun',x) end function f=fun(x) f=100*(x(1)^2-x(2))^2+(x( ...

  7. Sublime Text 3中文乱码

    Sublime Text 3是很好的代码编辑器,没有之一,因为她的性感高亮代码配色,更因为它的小巧,但是它默认不支持GBK的编码格式,因此打开GBK的代码文件,如果里面有中文的话,就会乱码,如下所示: ...

  8. c++版 nms

    目前这个代码运行会报一些错误,还要再修改修改才行 #include<iostream> #include<vector> #include<algorithm> # ...

  9. linux-top命令查看内存CPU

    转自:https://www.cnblogs.com/dragonsuc/p/5512797.html 查看多核CPU命令 mpstat -P ALL  和  sar -P ALL 说明:sar -P ...

  10. Spring源码分析(十五)获取单例

    本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例be ...