魔法森林 bzoj-3669 Noi-2014

题目大意:说不明白题意系列++……题目链接

注释:略。


想法:如果只有1个参量的话spfa、dij什么的都上来了。

两个参量的话我们考虑,想将所有的边按照a排序。

如果两个点:它们之间有两条路径,有一条比另一条劣。

那么我们完全可以将另一条弄掉。

排序之后维护生成树。

LCT的点维护的是实子树中第二参量的最大值。

如果当前边连接的两点之前不连通,直接连上。

如果联通,我们判断新边的第二参量和两点之间splay的最大参量之间的关系。

如果新边的第二参量大,直接舍去。反之,我们用新边替换旧边以得到所有可能答案。

此时,如果1到n联通,直接更新答案。

这个加边删边的过程,我们可以用LCT维护。

两点是否联通,可以用LCT中的find函数实现也可以用并查集维护。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 150050
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
int ch[N][2],f[N],rev[N],n,m,val[N],mx[N];
struct Node
{
int x,y,z,w;
}a[N];
inline bool cmp(const Node &x,const Node &y)
{
return x.z<y.z;
}
inline bool isroot(int p)
{
return ch[f[p]][0]!=p&&ch[f[p]][1]!=p;
}
inline void pushup(int p)
{
mx[p]=p;
if(val[mx[ls]]>val[mx[p]]) mx[p]=mx[ls];
if(val[mx[rs]]>val[mx[p]]) mx[p]=mx[rs];
}
inline void pushdown(int p)
{
if(!rev[p]) return;
swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]);
rev[ls]^=1; rev[rs]^=1; rev[p]=0;
}
void update(int p)
{
if(!isroot(p)) update(f[p]); pushdown(p);
}
void rotate(int x)
{
int y=f[x],z=f[y],k=get(x);
if(!isroot(y)) ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
pushup(y); pushup(x);
}
void splay(int x)
{
update(x);
for(int d;d=f[x],!isroot(x);rotate(x))
if(!isroot(d))
rotate(get(d)==get(x)?d:x);
}
void access(int p)
{
int t=0;
while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
}
inline void makeroot(int p)
{
access(p); splay(p); swap(ls,rs); rev[p]^=1;
}
inline void link(int x,int p)
{
makeroot(x); splay(p); f[x]=p;
}
void cut(int x,int p)
{
makeroot(x); access(p); splay(p); ls=f[x]=0;
}
int find(int p)
{
access(p); splay(p); while(ls) pushdown(p),p=ls;
return p;
}
int query(int x,int p)
{
makeroot(x); access(p); splay(p); return mx[p];
}
int main()
{
scanf("%d%d",&n,&m);
int tot=n;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].z,&a[i].w);
}
for(int i=1;i<=n;i++) mx[i]=i;
sort(a+1,a+m+1,cmp);
int ans=1<<30;
for(int i=1;i<=m;i++)
{
int x=a[i].x,y=a[i].y,z=a[i].z,w=a[i].w;
int t1=find(x),t2=find(y);
tot++;
if(t1!=t2)
{
val[tot]=w; mx[tot]=tot; link(x,tot); link(tot,y);
}else
{
int tmp=query(x,y);
if(val[tmp]>w)
{
cut(a[tmp-n].x,tmp); cut(a[tmp-n].y,tmp); val[tot]=w; mx[tot]=tot;
link(x,tot); link(y,tot);
}
}
if(find(1)==find(n))
{
ans=min(ans,z+val[query(1,n)]);
}
}
printf("%d\n",ans>100050?-1:ans);
}

小结:动态树问题一经转化就只能祭出LCT,别的能维护动态树的我也不会啊...

[bzoj3669][Noi2014]魔法森林_LCT_并查集的更多相关文章

  1. bzoj 3669: [Noi2014]魔法森林(并查集+LCT)

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  2. bzoj3669: [Noi2014]魔法森林 lct版

    先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...

  3. bzoj3669[Noi2014]魔法森林

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  4. BZOJ3669[Noi2014]魔法森林——kruskal+LCT

    题目描述 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住 ...

  5. BZOJ3669 [Noi2014]魔法森林(SPFA+动态加边)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  6. BZOJ3669: [Noi2014]魔法森林(瓶颈生成树 LCT)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3558  Solved: 2283[Submit][Status][Discuss] Descript ...

  7. [bzoj3669][Noi2014]魔法森林——lct

    Brief description 给定一个无向图,求从1到n的一条路径使得这条路径上最大的a和b最小. Algorithm Design 以下内容选自某HN神犇的blog 双瓶颈的最小生成树的感觉, ...

  8. bzoj3669: [Noi2014]魔法森林 lct

    记得去年模拟赛的时候好像YY出二分答案枚举a,b的暴力,过了55欸 然后看正解,为了将两维变成一维,将a排序,模拟Kruskal的加边过程,同时维护1到n的最大值,加入一条边e(u,v,a,b)时有以 ...

  9. 沉迷Link-Cut tree无法自拔之:[BZOJ3669][Noi2014] 魔法森林

    来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 $ $ 有一个很好的做法是 \(spfa\) ,但是我们不聊 \(spfa\) , 来聊 \(LCT\) \(L ...

随机推荐

  1. java线程系列---Runnable和Thread的区别 (转载)

    转自:http://blog.csdn.net/wwww1988600/article/details/7309070 在java中可有两种方式实现多线程,一种是继承 Thread类,一种是实现Run ...

  2. Appium + python - TouchAction操作

    from appium import webdriverfrom appium.webdriver.common.touch_action import TouchActionfrom appium. ...

  3. InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

    InnoDB锁机制之Gap Lock.Next-Key Lock.Record Lock解析 有意思,解释的很好

  4. Java—break跳出语句

    在开发代码时,常常会产生这样的疑惑:break跳出语句是如何应用的呢? 使用break的场景有两种:一.switch语句中.二.循环语句. 这里就不介绍switch语句,主要说一下break在循环中的 ...

  5. ArcGIS Android工程迁移到其他电脑不能打开的问题

    问题描述:当我把已经做好的ArcGIS Android工程想在其他电脑运行时,总是会提示报错.而报错的地方,正是出现在下面这条语句上. compile 'com.esri.arcgisruntime: ...

  6. CSS3利用box-shadow实现相框效果

    CSS3利用box-shadow实现相框效果 <style> html { overflow: hidden; background-color: #653845; background- ...

  7. Centos6.7 编译安装 Apache PHP

    Centos6.7 编译安装 Apache PHP 原文地址:http://www.cnblogs.com/caoguo/p/4968039.html ##### Apache 编译安装 #### [ ...

  8. (转)postgis常用函数介绍(二)

    http://blog.csdn.net/gisshixisheng/article/details/47903151 概述: 书接上文,本文继续讲解Postgres中常用的空间函数的使用. 常用函数 ...

  9. 浏览器的 local storage

    浏览器 local storage      本地存储 session storage    会话存储 cookies                  本地存储 1.     local stora ...

  10. Python 之pytesseract模块读取知乎验证码案例

    import pytesseract from PIL import Image import requests import time # 获取只会验证码图片并保存为本地 def get_data_ ...