luogu P2387 [NOI2014]魔法森林
这题似乎不好直接做,可以考虑按照\(a_i\)升序排序,然后依次加边更新答案
具体实现方法是用lct维护当前的树,这里需要维护链上最大的\(b_i\).每次加一条边,如果加完以后没有环直接加,否则找出链上最大的\(b_i\),如果这个\(b_i\)比当前的\(b_i\)小,加了肯定不优,否则就把那条边断掉,加上这条边.每次用当前\(a_i\)和1到n链上最大\(b_i\)更新答案
#include<bits/stdc++.h>
#define LL long long
#define db long double
#define il inline
using namespace std;
const int N=1e5+10;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,m,w[N],po[N][2],tt;
int fa[N],ch[N][2],id[N],vi[N];
bool tg[N];
bool nrt(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
void psup(int x)
{
id[x]=w[id[ch[x][0]]]>w[id[ch[x][1]]]?id[ch[x][0]]:id[ch[x][1]];
id[x]=w[id[x]]>w[vi[x]]?id[x]:vi[x];
}
void rev(int x){if(x) swap(ch[x][0],ch[x][1]),tg[x]^=1;}
void psdn(int x){if(tg[x]) rev(ch[x][0]),rev(ch[x][1]),tg[x]=0;}
void ppush(int x)
{
if(nrt(x)) ppush(fa[x]);
psdn(x);
}
void rot(int x)
{
int y=fa[x],z=fa[y],yy=ch[y][1]==x,w=ch[x][!yy];
if(nrt(y)) ch[z][ch[z][1]==y]=x;
ch[y][yy]=w,ch[x][!yy]=y;
if(w) fa[w]=y;
fa[x]=z,fa[y]=x;
psup(y);
}
void spl(int x)
{
ppush(x);
while(nrt(x))
{
int y=fa[x];
if(nrt(y)) ((ch[y][1]==x)^(ch[fa[y]][1]==y))?rot(x):rot(y);
rot(x);
}
psup(x);
}
void acs(int x)
{
for(int y=0;x;y=x,x=fa[x])
spl(x),ch[x][1]=y,psup(x);
}
void mkrt(int x)
{
acs(x),spl(x),rev(x);
}
int fdrt(int x)
{
acs(x),spl(x);
psdn(x);
while(ch[x][0]) x=ch[x][0],psdn(x);
return x;
}
void split(int x,int y)
{
mkrt(x),acs(y),spl(y);
}
void link(int x,int y,int z)
{
mkrt(x);
if(fdrt(y)!=x)
{
mkrt(y);
w[++tt]=z,vi[tt]=tt,po[tt][0]=x,po[tt][1]=y;
fa[x]=fa[y]=tt;
return;
}
acs(y),spl(y);
int ii=id[y];
if(w[ii]<=z) return;
mkrt(po[ii][0]),acs(po[ii][1]),spl(ii);
fa[po[ii][0]]=fa[po[ii][1]]=ch[ii][0]=ch[ii][1]=0,psup(ii);
w[ii]=z,po[ii][0]=x,po[ii][1]=y;
mkrt(x),mkrt(y);
fa[x]=fa[y]=ii;
}
struct edge
{
int x,y,a,b;
bool operator < (const edge &bb) const {return a<bb.a;}
}e[N];
int main()
{
n=rd(),m=rd();
for(int i=1;i<=m;++i)
{
int x=rd(),y=rd(),a=rd(),b=rd();
e[i]=(edge){x,y,a,b};
}
sort(e+1,e+m+1);
tt=n,w[0]=-(1<<30);
int ans=1<<30;
for(int i=1;i<=m;++i)
{
if(e[i].x==e[i].y) continue;
link(e[i].x,e[i].y,e[i].b);
mkrt(1);
if(fdrt(n)==1) ans=min(ans,e[i].a+w[id[n]]);
}
printf("%d\n",ans<(1<<29)?ans:-1);
return 0;
}
luogu P2387 [NOI2014]魔法森林的更多相关文章
- [Luogu P2387] [NOI2014]魔法森林 (LCT维护边权)
题面 传送门:https://www.luogu.org/problemnew/show/P2387 Solution 这题的思想挺好的. 对于这种最大值最小类的问题,很自然的可以想到二分答案.很不幸 ...
- P2387 [NOI2014]魔法森林(LCT)
P2387 [NOI2014]魔法森林 LCT边权维护经典题 咋维护呢?边化为点,边权变点权. 本题中我们把边对关键字A进行排序,动态维护关键字B的最小生成树 加边后出现环咋办? splay维护最大边 ...
- 洛谷 P2387 [NOI2014]魔法森林 解题报告
P2387 [NOI2014]魔法森林 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2 ...
- 洛谷P2387 [NOI2014]魔法森林(lct维护最小生成树)
题目描述 为了得到书法大家的真传,小 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\)有了一条路径,就更新最小答案.这个过程就相当于 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT,Splay)
在XZY&XZZ巨佬的引领下,一枚蒟蒻终于啃动了这道题...... 这次还是第一次写LCT维护边权,还要化边为点,思路乱七八糟的,写起来也不顺手,还好调了许久终于AC啦. 贪心排序按一个关键字 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT)
在XZY&XZZ巨佬的引领下,一枚蒟蒻终于啃动了这道题...... 这次还是第一次写LCT维护边权,还要化边为点,思路乱七八糟的,写起来也不顺手,还好调了许久终于AC啦. 贪心排序按一个关键字 ...
- P2387 [NOI2014]魔法森林
传送门 如果一条边只要考虑 $a$ 的限制,那么显然最小生成树 但是现在有 $a,b$ 两个限制,所以考虑按 $a$ 从小到大枚举边,动态维护 $b$ 的最小生成树 考虑新加入的一条边 $x,y$ , ...
随机推荐
- Flask 自定义过滤器多个参数传入
非完整HTML文件: <div class="container" style="margin-top:50px;"> <div class= ...
- c 结构体 & 函数指针模拟实现一个java class(类) 和方法
闲来无事,纯粹练习. student.h #ifndef STUDENT_H_INCLUDED #define STUDENT_H_INCLUDED #include <memory.h> ...
- 神经网络中w,b参数的作用(为何需要偏置b的解释)
http://blog.csdn.net/xwd18280820053/article/details/70681750 可视图讲解神经元w,b参数的作用 在我们接触神经网络过程中,很容易看到就是这样 ...
- ElasticSearch6.5.0 【字段类型】
字符串类型 text 适合全文索引,有分析的过程 keyword 适合结构化的数据,比如地址.电话号码... 数字 long [带符号64位整数]范围:-263 ~ 263-1 integer ...
- ajax多表单序列化
今天在修一个后台接收参数为空值的bug 找了好久才发现原来是form表单合拼参数的时候把参数给搞没了 (我也不知道为什么啊—_—!) //对表单进行Json对象序列化 (function($){ $. ...
- HTML学习笔记Day11
一.CSS文档统筹 (一)网页自身的优化 (二)CSS规范 1.命名方法(语义化命名,结构化命名) ID:结构化 header footer class: .border0 . red: ...
- 为什么wait()和notify()属于Object类
关于wait()暂停的是持有锁的对象,所以想调用wait()必须为:对象.wait(); notify()唤醒的是等待锁的对象,调用:对象.notify(); 如下: Object obj = new ...
- 基于python调用libvirt API
基于python调用libvirt API 1.程序代码 #!/usr/bin/python import libvirt import sys def createConnection(): con ...
- URLSearchParams 接口
URLSearchParams 接口定义了很多个用来处理 URL 参数串的方法 他可以把对象转变成url上面查询信息的写法,例如a=1&b=2 可以把请求路由中的字符串 key=1 ,拼接 ...
- 前端面试题整理—HTTP篇
1.常见的HTTP方法有哪些? GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器 POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用PO ...