洛谷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每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
随机推荐
- 洛谷P3306 随机数生成器
题意:给你一个数列,a1 = x,ai = (A * ai-1 + B) % P,求第一个是t的是哪一项,或者永远不会有t. 解:循环节不会超过P.我们使用BSGS的思想,预处理从t开始跳√P步的,插 ...
- 如约而至(walk)
LCA大佬的做法: 考虑暴力的高斯消元,我们优化它. $\sum\limits_{j} gcd(i,j)^{c-d} i^d j^d x_j=b_i$ $\sum\limits_{j} gcd(i,j ...
- GitBook的使用方法
---恢复内容开始--- 由于近期工作中使用gitbook编写讲义,现把出现的问题总结下: 1 . gitbook的安装 Gitbook与word等办公软件类似,能够编写文档,Gitbook中编写文档 ...
- POSTMAN调试接口post对象
APP回传设备信息,设备信息对象里边包含以下字段 后台是java ssh接收 用对象属性自动封装比较方便 所以,使用 方式进行回传 而不是使用网上说的 设置如下图
- dll加载过程全局变量会先初始化
在一个生成dll的工程中看到一个文件只有一句全局变量初始化的代码,很好奇为什么这句代码在dll加载的时候就会执行,因此断点调试发现 __declspec(noinline) BOOL __cdecl ...
- 2018-2-13-wpf-PreviewTextInput-在鼠标输入获得-_u0003
title author date CreateTime categories wpf PreviewTextInput 在鼠标输入获得 � lindexi 2018-2-13 17:23:3 +08 ...
- 简单的layui二级联动
用layui实现省市二级联动, 需要注意的是使用layui之后, 你看到的下拉选框就不是option了,而是一些div 1.select表单 2.JS, ajax返回的是普通的数组
- Thinkphp 不足之处
1.报错机制 //控制器里面直接输出如下内容,代码不提示.TP报错机制已经开启 echo $aaaaaa; bbbbbbbbb; eco bbbbbbbb; 正常应该给出以下提示 Notice: Un ...
- Hdu 2389 二分匹配
题目链接 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 655350/165535 K (Ja ...
- 常见的php攻击(6种攻击详解)
1.SQL注入 SQL注入是一种恶意攻击,用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行.还有一种是通过system()或exec()命令注入的,它具有相同的SQL注入机制,但只针对sh ...