题目链接:BZOJ - 3669

题目分析

如果确定了带 x 只精灵A,那么我们就是要找一条 1 到 n 的路径,满足只经过 Ai <= x 的边,而且要使经过的边中最大的 Bi 尽量小。

其实就是一个按照 Bi 建立的 MST 上 1 到 n 的路径。只能使用 Ai <= x 的边。

那么,如果我们从小到大枚举 x ,这样可以使用的边就不断增加,就是在加边的同时维护 MST ,用 LCT 来做就可以了。

如果新加入一条边 (u, v, w) ,并且原 MST 上 u 到 v 的路径中边权最大的边的边权大于 w ,那么就删掉那条边权最大的边,然后把这条新加入的边连到 MST 中。

备注:在 Cut 不够优的边时,我之前将代码写出了非常可怕的 BUG ,但是由于神奇的写法的巧合,这个 BUG 并没有造成后果,我用错误的代码 AC 了两道题..

现在下方的代码是正确的了。

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm> using namespace std; inline void Read(int &Num)
{
char c = getchar();
while (c < '0' || c > '9') c = getchar();
Num = c - '0'; c = getchar();
while (c >= '0' && c <= '9')
{
Num = Num * 10 + c - '0';
c = getchar();
}
} inline int gmax(int a, int b) {return a > b ? a : b;}
inline int gmin(int a, int b) {return a < b ? a : b;} const int MaxN = 50000 + 5, MaxM = 100000 + 5, MaxT = 150000 + 5, INF = 999999999; int n, m, Ans;
int Father[MaxT], Son[MaxT][2], V[MaxT], T[MaxT]; bool isRoot[MaxT], Rev[MaxT]; struct ES
{
int u, v, p, q;
} E[MaxM]; inline bool Cmp(ES e1, ES e2)
{
return e1.p < e2.p;
} /**************************** LCT Start *******************************/ inline int Tmax(int a, int b) {return V[a] > V[b] ? a : b;} inline void Update(int x)
{
T[x] = Tmax(x, Tmax(T[Son[x][0]], T[Son[x][1]]));
} inline void Reverse(int x)
{
Rev[x] = !Rev[x];
swap(Son[x][0], Son[x][1]);
} inline void PushDown(int x)
{
if (!Rev[x]) return;
Rev[x] = false;
if (Son[x][0]) Reverse(Son[x][0]);
if (Son[x][1]) Reverse(Son[x][1]);
} inline int GetDir(int x)
{
if (x == Son[Father[x]][0]) return 0;
else return 1;
} void Rotate(int x)
{
int y = Father[x], f;
PushDown(y); PushDown(x);
f = GetDir(x) ^ 1;
if (isRoot[y])
{
isRoot[y] = false;
isRoot[x] = true;
}
else
{
if (y == Son[Father[y]][0]) Son[Father[y]][0] = x;
else Son[Father[y]][1] = x;
}
Father[x] = Father[y];
Son[y][f ^ 1] = Son[x][f];
if (Son[x][f]) Father[Son[x][f]] = y;
Son[x][f] = y;
Father[y] = x;
Update(y); Update(x);
} void Splay(int x)
{
int y;
while (!isRoot[x])
{
y = Father[x];
if (isRoot[y])
{
Rotate(x);
break;
}
if (GetDir(y) == GetDir(x)) Rotate(y);
else Rotate(x);
Rotate(x);
}
} int Access(int x)
{
int y = 0;
while (x != 0)
{
Splay(x);
PushDown(x);
if (Son[x][1]) isRoot[Son[x][1]] = true;
Son[x][1] = y;
if (y) isRoot[y] = false;
Update(x);
y = x;
x = Father[x];
}
return y;
} inline void Make_Root(int x)
{
int t = Access(x);
Reverse(t);
} inline void Link(int x, int y)
{
Make_Root(x);
Splay(x);
Father[x] = y;
} inline void Cut(int x, int y)
{
Make_Root(x);
Access(y);
Splay(y);
PushDown(y);
isRoot[Son[y][0]] = true;
Father[Son[y][0]] = 0;
Son[y][0] = 0;
Update(y);
} inline int Find_Root(int x)
{
int t = Access(x);
while (Son[t][0] != 0) t = Son[t][0];
return t;
} /**************************** LCT End *******************************/ int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i)
{
Read(E[i].u); Read(E[i].v);
Read(E[i].p); Read(E[i].q);
}
sort(E + 1, E + m + 1, Cmp); // by ES.p
for (int i = 1; i <= m; ++i) V[n + i] = E[i].q;
for (int i = 1; i <= n + m; ++i)
{
isRoot[i] = true;
Father[i] = 0;
T[i] = i;
}
Ans = INF;
int t, CutE;
for (int i = 1; i <= m; ++i)
{
if (Find_Root(E[i].u) != Find_Root(E[i].v))
{
Link(E[i].u, n + i); Link(E[i].v, n + i);
}
else
{
Make_Root(E[i].u);
t = Access(E[i].v);
if (V[T[t]] > E[i].q)
{
CutE = T[t];
Cut(CutE, E[CutE - n].u); Cut(CutE, E[CutE - n].v);
Link(E[i].u, n + i); Link(E[i].v, n + i);
}
}
if (Find_Root(1) == Find_Root(n))
{
Make_Root(1);
t = Access(n);
Ans = gmin(Ans, E[i].p + V[T[t]]);
}
}
if (Ans == INF) Ans = -1;
printf("%d\n", Ans);
return 0;
}

  

[BZOJ 3669] [Noi2014] 魔法森林 【LCT】的更多相关文章

  1. BZOJ 3669: [Noi2014]魔法森林( LCT )

    排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...

  2. bzoj 3669: [Noi2014]魔法森林 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec  ...

  3. bzoj 3669: [Noi2014] 魔法森林 LCT版

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

  4. BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]

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

  5. BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)

    传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...

  6. bzoj 3669: [Noi2014]魔法森林

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

  7. bzoj 3669: [Noi2014]魔法森林 动态树

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 202[Submit][Status] ...

  8. bzoj 3669: [Noi2014]魔法森林 -- 动点spfa

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...

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

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

随机推荐

  1. Linux下jvm、tomcat、mysql、log4j优化配置笔记[转]

    小菜一直对操作系统心存畏惧,以前也很少接触,这次创业购买了Linux云主机,由于木有人帮忙,只能自己动手优化服务器了.... 小菜的云主机配置大致为:centeos6(32位),4核心cpu,4G内存 ...

  2. hdu 3586 Information Disturbing(树形dp + 二分)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:   hdu-3586 题意 给一棵n个节点的树,节点编号为1-n,根节点为1.每条边有权值,砍掉一条边要花费 ...

  3. myeclipse自动生成可持久化类的映射文件的方法

    1.打开DB Browser,新建一个数据库的连接,找到想要持久化操作的数据库表的图标,右键选择hibernate reverse engineering 2.之后出现如下所示: java src f ...

  4. windows修改mysql默认字符集不成功

    今天下午弄了半天,终于把mysql的默认字符集弄成了, 按照网上的说法,什么修改mysql下面的my.ini文件,把参数设置成utf-8,我反复操作,结果都是不成功,后来我把mysql5.0卸载了,网 ...

  5. 初步掌握HBase

    1.HBase概述 HBase是hadoop生态系统中的重要组成部分,是一个开源的.面向列.适合存储海量非结构化数据或半结构化数据,具备高可靠性.高性能.可灵活扩展伸缩.支持实时数据读写的分布式存储系 ...

  6. The Class Loader Hierarchy--转载

    Class loaders in the Application Server runtime follow a delegation hierarchy that is illustrated in ...

  7. Memcache及telnent命令详解--转

    1.启动Memcache 常用参数memcached 1.4.3-p <num>      设置端口号(默认不设置为: 11211)-U <num>      UDP监听端口 ...

  8. WPF组件开发之组件的基类

    之前在网上看到很多关于组件开发的资料,但真正可以用到框架内的却很少.今天贴出自己做的组件,并适合大部分框架的代码. 组件开发需要先做出组件的基类,然后由其他的各类组件去继承这个基类,下面是组件基类的代 ...

  9. 分分钟教你集成沉浸式侧滑关闭Activity

    网上搜索侧滑关闭Activity,几乎没有系统状态栏跟随页面一起联动的,有明显的撕裂感,而这里则是状态栏跟随页面联动的,说来集成也是简单,等会你就知道了. 个人习惯,写博客前喜欢先截图 1.首先以项目 ...

  10. 【锋利的jQuery】学习笔记02

    第二章 jQuery选择器 一.jQuery选择器的优势 写法简洁 $("div") 支持css2和css3选择器(对于css3选择器支持这一项,我认为应该是jQuery首先创造并 ...