洛谷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每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
随机推荐
- Luogu P2051 [AHOI2009]中国象棋(dp)
P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...
- Frank Dellaert Slam Speech 20190708
Georgia Institue of Tecknology 3D Models from Community Databases Spatiotemporal Reconstruction 4D C ...
- 本地文件访问json数据格式,在chrome中没反应
原因:存在跨域问题 在JavaScript的安全性上,有一条很重要的安全限制,叫“同源策略”.就是一个脚本只能读取与它同源(如由同一个主机下载,通过同一个端口下载或者下载协议相同)的窗口或者文档的属性 ...
- Spring松耦合示例(转)& IOC
Spring松耦合示例 轻松学习Spring<一> IoC容器和Dependency Injection模式 最近公司需要,项目中要用到Spring和Ibatis.趁着过年好好学习学习.I ...
- jnhs-Myeclipse 10注册教程unable to access jarfile cracker.jar
直接双击jar文件就可以 打开后,随便写一个名字 然后复制LICENSE_KEY的内容,打开myeclipse 在Code那里粘贴你刚才复制的内容,然后点击Save & Active Now ...
- MySQL数据库的全局锁和表锁
1.概念 数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 2.锁的分类 根据加锁的范围, ...
- Java方法传参的问题
1.基本数据类型(byte,short,int,long,float,double,boolean,char)的值传递,不改变其值 2.引用数据类型的值传递,改变其值 3.String类型虽然是引用数 ...
- Flask中的session机制
cookie和sessioncookie:网站中,http请求是无状态的,第一次和服务器连接后并且登陆成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是解决了改问题,第一次 ...
- SpringBooot-基础<1>-构建项目
SpringBooot-基础<1>-构建项目 使用Springboot创建web工程,我使用的工具:STS,JDK1.8 1. File -> New -> Maven Pro ...
- java-异常处理2
一 编译时异常和运行时异常的区别 java认为如果你的程序有问题,你应该让调用者知道. 例如:面包,长毛了.用户去买了,用户可能会挂 .应该在面包上贴上标签(异常). java 如果在函数内抛出Exc ...