[NOI2014]魔法森林(LCT)
蒟蒻又发现自己还没写过LCT……
首先显然按照权值a从小到大排序,维护b的最小生成树。然后直接扫,代价是加入b的最大值,然后动态加边,因为有边权,所以在lct中边应该理解为点。每次连接(u,v)时,若不连通则直接连起来,反之则需选择b最大的边断开。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+;
struct node{int a,b,x,y;}q[N];
int n,m,len,fa[N],lc[N],rc[N],rev[N],b[N],val[N],s[N],f[N];
bool cmp(node a,node b){return a.y<b.y;}
int dir(int x){return x==rc[fa[x]];}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void union1(int x,int y){x=find(x),y=find(y);if(x!=y)f[x]=y;}
bool isroot(int x){return!fa[x]||lc[fa[x]]!=x&&rc[fa[x]]!=x;}
void pushup(int x)
{
s[x]=x;
if(lc[x]&&val[s[lc[x]]]>val[s[x]])s[x]=s[lc[x]];
if(rc[x]&&val[s[rc[x]]]>val[s[x]])s[x]=s[rc[x]];
}
void pushdown(int x)
{
if(rev[x])
{
swap(lc[x],rc[x]);
if(lc[x])rev[lc[x]]^=;
if(rc[x])rev[rc[x]]^=;
rev[x]=;
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y],w=x==lc[y]?rc[x]:lc[x];
if(z&&!isroot(y))(y==lc[z]?lc[z]:rc[z])=x;
fa[x]=z,fa[y]=x;
if(w)fa[w]=y;
if(x==lc[y])rc[x]=y,lc[y]=w;else lc[x]=y,rc[y]=w;
pushup(y),pushup(x);
}
void splay(int x)
{
int len=,y=x;b[]=x;
while(!isroot(y))b[++len]=fa[y],y=fa[y];
for(int i=len;i;i--)pushdown(b[i]);
while(!isroot(x))
{
if(!isroot(fa[x]))
{
if(dir(x)==dir(fa[x]))rotate(fa[x]);
else rotate(x);
}
rotate(x);
}
pushup(x);
}
void access(int x)
{
int y=;
while(x)
{
splay(x),rc[x]=y;
if(y)fa[y]=x;
pushup(x),y=x,x=fa[x];
}
}
int findrt(int x)
{
access(x),splay(x),pushdown(x);
while(lc[x])x=lc[x];
splay(x);
return x;
}
void reverse(int x){access(x),splay(x),rev[x]^=;}
void link(int x,int y){reverse(x),fa[x]=y;}
void cut(int x,int y){reverse(x),access(y),splay(y),lc[y]=fa[x]=,pushup(y);}
int query(int x,int y){reverse(x),access(y),splay(y);return s[y];}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)scanf("%d%d%d%d",&q[i].a,&q[i].b,&q[i].x,&q[i].y);
sort(q+,q+m+,cmp);
for(int i=;i<=n+m;i++)f[i]=s[i]=i;
for(int i=n+;i<=n+m;i++)val[i]=q[i-n].x;
int ans=2e9;
for(int i=;i<=m;i++)
{
int u=q[i].a,v=q[i].b;
bool flag=;
if(find(u)==find(v))
{
int w=query(u,v);
if(val[w]>q[i].x)cut(q[w-n].a,w),cut(w,q[w-n].b);else flag=;
}
else union1(u,v);
if(flag)link(u,i+n),link(i+n,v);
if(find()==find(n))ans=min(ans,q[i].y+val[query(,n)]);
}
if(ans<2e9)printf("%d",ans);else puts("-1");
}
[NOI2014]魔法森林(LCT)的更多相关文章
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- [NOI2014]魔法森林 LCT
题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...
- loj2245 [NOI2014]魔法森林 LCT
[NOI2014]魔法森林 链接 loj 思路 a排序,b做动态最小生成树. 把边拆成点就可以了. uoj98.也许lct复杂度写假了..越卡常,越慢 代码 #include <bits/std ...
- bzoj3669: [Noi2014]魔法森林 lct版
先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...
- 【BZOJ3669】[Noi2014]魔法森林 LCT
终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...
- bzoj 3669: [Noi2014] 魔法森林 LCT版
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...
- P2387 [NOI2014]魔法森林 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT)
魔法森林 题目传送门 解题思路 把每条路按照\(a\)的值从小到大排序.然后用LCT按照b的值维护最小生成树,将边按照顺序放入.如果\(1\)到\(n\)有了一条路径,就更新最小答案.这个过程就相当于 ...
随机推荐
- 前端第一篇---前端基础之HTML内容
前端基础之HTML内容 阅读目录(Content) 一.HTML初识 1.web服务本质 2.HTML是什么 3.HTML不是什么 二.HTML文档结构 三.HTML标签格式 四.HTML注释 五.H ...
- h5页面列表滚动加载数据
h5列表滚动加载数据很常见,以下分享下今天做的案例: 前言 这个效果实现需要知道三个参数 1. scrollTop -- 滚动条距离顶部的高度 2. scrollHeight -- 当前页面的总高度( ...
- PWC6199:Generated servlet error:Only a type can be imported. org.apache.jasper.tagplugins.jstl.core.ForEach resolves to a package
<%@ import="org.apache.jasper.tagplugins.jstl.core.ForEach"%> 去掉这条语句,就不报错了.所以问题就出在这里 ...
- BZOJ 5059 前鬼后鬼的守护
题解: 解法一:用函数斜率什么的,不会,留坑 解法二: 某一个序列都变成一个值那么中位数最优 加入一个元素,与前面那一段区间的中位数比较 x>=mid什么事也不做 x<mid合并两端区间 ...
- python中__str__与__repr__
(1)背景 python中,对于类(自定义类)的实例对象的默认显示既没有太大用处,也不美观.比如: class adder: def __init__(self,value=0): self.data ...
- equals与hashcode分析
我们经常在面经中看到这样的问题,为什么重写equals方法就一定要重写hashcode方法.本文就是分析这个问题. <!--more--> 在阿里巴巴java开发手册中就给出了这样的规则. ...
- C# 基本元素
一.构成C#的基本元素 注释和空白编译器不会编译,自动忽略:而标记是可以通过编译器编译的. 关键字 (keyword) 官方定义:关键字是类似标识符的保留的字符序列,不能用作标识符(以 @ 字符开头时 ...
- [SUCTF 2019]EasyWeb
0x00 知识点 本题知识量巨大,把我给看傻了..盯着网上师傅们的博客看了好久.. 知识点1 构造不包含数字和字母的webshell 思路来自p牛 参考链接: https://www.leaveson ...
- LeetCode刷题笔记(1-9)
LeetCode1-9 本文更多是作为一个习题笔记,没有太多讲解 1.两数之和 题目请点击链接 ↑ 最先想到暴力解法,直接双循环,但是这样复杂度为n平方 public int[] twoSum(int ...
- WebView的学习
加载网页: 加载URL(网络或者本地assets文件下的html文件) 加载html代码 Native和JavaScript相互调用(利于混合开发) 1.加载网络URL webview.loadUrl ...