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. Js 运算符(加减乘除)

    1.加法 + +NaN //NaN,有一个为NaN就为NaN var box=Infinity+Infinity //Infinity var box=-Infinity + -Infinity // ...

  2. UI(一)

    1.AfxWinMain 首先,MFC程序先执行到TheApp实例化对象也就是通过这句CTestApp the App来实例化对象的然后,调用CTestApp构造函数分配内存空间 然后,就调用了Afx ...

  3. RabbitMQ学习以及与Spring的集成(二)

    本文介绍RabbitMQ的一些基本概念. RabbitMQ服务可以安装在独立服务器上,通过配置的账户和ip访问使用.也就是说,RabbitMQ和使用它的应用可以部署在不同的服务器上.RabbitMQ的 ...

  4. PHP设计模式系列 - 委托模式

    委托模式 通过分配或委托其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. 应用场景 设计了一个cd类,类中有mp3播放模式,和mp4播放模式 改进前,使用cd类的播放模式,需要在实例化的 ...

  5. 中间人攻击-MITM攻击

    中间人攻击(Man-in-the-MiddleAttack,简称“MITM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术手段将受入侵者控制的一台计算机虚拟放置在网络连接中的两台通信计算机 ...

  6. Hive学习之路 (十四)Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANK

    概述 本文中介绍前几个序列函数,NTILE,ROW_NUMBER,RANK,DENSE_RANK,下面会一一解释各自的用途. 注意: 序列函数不支持WINDOW子句.(ROWS BETWEEN) 数据 ...

  7. jQuery.fn.extend()

    jQuery.fn.extend() extend()方法是定义在jQuery构造函数的prototype对象上面的一个方法,这样做就能使得所有jQuery对象的实例都能共享这个方法.jQuery构造 ...

  8. python matplotlib quiver——画箭头、风场

    理解参考:https://blog.csdn.net/liuchengzimozigreat/article/details/84566650 以下实例 import numpy as np impo ...

  9. Kafka设计解析(十五)Kafka controller重设计

    转载自 huxihx,原文链接 Kafka controller重设计 目录 一.Controller是做什么的 二.Controller当前设计 三.Controller组成 四.Controlle ...

  10. Kafka设计解析(十三)Kafka消费组(consumer group)

    转载自 huxihx,原文链接 Kafka消费组(consumer group) 一直以来都想写一点关于kafka consumer的东西,特别是关于新版consumer的中文资料很少.最近Kafka ...