洛谷2387 BZOJ3669魔法森林题解
这道题被很多人用spfa水了过去,表示很。。。
其实spfa很好卡,这组数据可以卡掉大多数spfa
链接:密码:rjvk
这里讲一下LCT的做法
我们按照a将边排序,然后依次添加
每次加入时若两边没有联通,就直接加入,否则就
检查两边的路径中权值b最大的权值是多少,如果大于当前加入边的权值
就将该边删掉,然后将当前边加入
注意lct维护边权时需要用到拆点
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstring>
# include<cstdio>
using namespace std;
const int mn = ;
const int inf = ;
struct edge{int u,v,a,b;};
edge e[mn];
bool cmp(const edge &x,const edge &y)
{
if(x.a==y.a) return x.b<y.b;
else return x.a<y.a;
}
int n,m,ans,fa[mn];
int _find(int x) {return x==fa[x] ? x : fa[x]=_find(fa[x]);}
struct LCT{
int val[mn],fa[mn],c[mn][],mx[mn],st[mn];
//mx[x]表示子树中权值最大的点的编号
bool rev[mn];
bool nroot(int x)
{
return c[fa[x]][]==x || c[fa[x]][]==x;
}
void zhuan(int x)
{
swap(c[x][],c[x][]);
rev[x]^=;
}
void pushdown(int x)
{
if(rev[x])
{
rev[x]=;
if(c[x][]) zhuan(c[x][]);
if(c[x][]) zhuan(c[x][]);
}
}
void updown(int x)
{
mx[x]=x;
if(c[x][])
{
if(val[mx[c[x][]]]>val[mx[x]])
mx[x]=mx[c[x][]];
}
if(c[x][])
{
if(val[mx[c[x][]]]>val[mx[x]])
mx[x]=mx[c[x][]];
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y],flag;
if(c[y][]==x) flag=;
else flag=;
if(nroot(y))
{
if(c[z][]==y) c[z][]=x;
else c[z][]=x;
}
c[y][flag^]=c[x][flag],fa[c[x][flag]]=y;
c[x][flag]=y;
fa[y]=x,fa[x]=z;
updown(y);
updown(x);
}
void splay(int x)
{
int top=;
st[++top]=x;
for(int i=x;nroot(i);i=fa[i])
st[++top]=fa[i];
for(;top;top--) pushdown(st[top]);
while(nroot(x))
{
int y=fa[x],z=fa[y];
if(nroot(y))
{
if((c[y][]==x) ^ (c[z][]==y))
rotate(x);
else rotate(y);
}
rotate(x);
}
updown(x);
}
void access(int x)
{
int t=;
while(x){splay(x);c[x][]=t;updown(x);t=x;x=fa[x];}
}
void makeroot(int x)
{
access(x);
splay(x);
zhuan(x);
}
void link(int x,int y)
{
makeroot(x);
fa[x]=y;
}
void cut(int x,int y)
{
makeroot(x);
access(y);
splay(y);
c[y][]=fa[x]=;
updown(y);
}
int query(int x,int y)
{
makeroot(x);
access(y);
splay(y);
return mx[y];
}
}T;
void pre()
{
for(int i=;i<=n;i++)
fa[i]=i;
for(int i=;i<=m;i++)
T.val[i+n]=e[i].b;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);
sort(e+,e++m,cmp);
ans=inf;
pre();
/* for(int i=1;i<=m;i++)
printf("%d %d\n",e[i].a,e[i].b);*/
for(int i=;i<=m;i++)
{
int x=e[i].u,y=e[i].v;
int xx=_find(x),yy=_find(y);
if(xx!=yy)
{
fa[xx]=yy;
T.link(x,i+n);
T.link(i+n,y);
}
else {
int k=T.query(x,y);
if(T.val[k]>e[i].b)
{
T.cut(e[k-n].u,k);
T.cut(k,e[k-n].v);
T.link(x,i+n);
T.link(i+n,y);
}
}
if(_find()==_find(n))
ans=min(ans,e[i].a+T.val[T.query(,n)]);
// printf("%d %d\n",e[i].a,T.query(1,n));
}
if(ans==inf) printf("-1");
else printf("%d",ans);
return ;
}
洛谷2387 BZOJ3669魔法森林题解的更多相关文章
- 洛谷 2387 NOI2014魔法森林 LCT
[题解] 我们先把边按照$a$值从小到大排序,并按照这个顺序加边. 如果当前要加入的边连接的两点$u$与$v$已经是连通的,那么直接加入这条边就会出现环.这时我们需要删除这个环中$b$值最大的边.因此 ...
- 洛谷2387 NOI2014魔法森林(LCT维护最小生成树)
本题是运用LCT来维护一个最小生成树. 是一个经典的套路 题目中求的是一个\(max(a_i)+max(b_i)\)尽可能小的路径. 那么这种的一个套路就是,先按照一维来排序,然后用LCT维护另一维 ...
- 洛谷P2387 [NOI2014]魔法森林(lct维护最小生成树)
题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...
- 洛谷 P2387 [NOI2014]魔法森林 解题报告
P2387 [NOI2014]魔法森林 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT)
魔法森林 题目传送门 解题思路 把每条路按照\(a\)的值从小到大排序.然后用LCT按照b的值维护最小生成树,将边按照顺序放入.如果\(1\)到\(n\)有了一条路径,就更新最小答案.这个过程就相当于 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT,Splay)
在XZY&XZZ巨佬的引领下,一枚蒟蒻终于啃动了这道题...... 这次还是第一次写LCT维护边权,还要化边为点,思路乱七八糟的,写起来也不顺手,还好调了许久终于AC啦. 贪心排序按一个关键字 ...
- 洛谷P2387 [NOI2014]魔法森林(LCT)
在XZY&XZZ巨佬的引领下,一枚蒟蒻终于啃动了这道题...... 这次还是第一次写LCT维护边权,还要化边为点,思路乱七八糟的,写起来也不顺手,还好调了许久终于AC啦. 贪心排序按一个关键字 ...
- 【洛谷P2387】魔法森林
题目大意:给定一个 N 个点,M 条边的无向图,边有两个边权 a, b,求从 1 号节点到 N 号节点路径的两个权值和的最大值最小是多少. 题解: 对于有两个属性的结构的最优化问题,可以考虑先按照其中 ...
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
随机推荐
- Java TimeUnit使用
TimeUnit是java.util.concurrent包下面的一个类,表示给定单元粒度的时间段. 常用的颗粒度 TimeUnit.DAYS //天 TimeUnit.HOURS //小时 Time ...
- Leetcode129. Sum Root to Leaf Numbers求根到叶子节点数字之和
给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字. 例如,从根到叶子节点路径 1->2->3 代表数字 123. 计算从根到叶子节点生成的所有 ...
- 万能的pdftk
pdftk (the pdf toolkit) 是一个功能强大的命令行的 PDF 文件编辑软件,可以合并/分割 PDF 文档.对 PDF 文件加密解密.给 PDF 文档加水印.从 PDF 文档中解出附 ...
- TCP/TP:DNS区域(Zone)
之前阅读资料不是特别明白,看到一个博主的解释,豁然开朗,特此记录. https://blog.csdn.net/huangzx3/article/details/79347556 DNS区域(ZONE ...
- H5C3--盒子模型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HTML 语法简要总结
HTML基本语法 认识网页 网页主要由文字.图像和超链接等元素构成.当然,除了这些元素,网页中还可以包含音频.视频以及Flash等. 常见浏览器内核介绍 浏览器是网页运行的平台,常用的浏览器有IE.火 ...
- 基于VSCode的vue单文件组件模板设置---一次设置,可爽终生
第一步: 第二步: 第三步: 打开vue.json文件后,如果是初次设置,应该如下图所示,绿色注释部分不用管,注意那两个白色大括号 第四步:在大括号内全部粘贴如下代码,保存即可完成vue模板的设置 & ...
- 在多版本python的pip的安装与对应包的安装
最近花了好长时间在搞这个,由于Deepin下python有两个版本,并且都没有安装pip,之前的博文默认安装pip给python2.7,结果各种问题,在此将之前走过的弯路整合起来: 首先,安装pip ...
- mysql8 navicat
先把root账户的加密规则改回去 ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; 然后使用新 ...
- JAVA--养成好的编程习惯
原文地址:http://user.qzone.qq.com/1159340782/2 略微牺牲一些性能,换来更好的可读性和可维护性是好的选择.以下不提倡和提倡的写法仅供参考. 代码中不提倡的写法 序号 ...