bzoj 3669: [Noi2014]魔法森林 (LCT & kruskal)
这道题呢,
首先按照关键字a排序,然后不断地加边,用lct维护这个过程
具体实现: 先按照关键字a排序,枚举每一条边,判断两点是否已经联通(kruskal 部分)如果联通,就在两点路径间寻找最大的b, 和这条边的b值相比较,如果更大一些,就切断u,v之间的路径, 并连上这条边;
如果不联通,就让它联通(好随意啊= =
最后寻找路径之间最大的b + 当前的a,和原来的答案相比较。
剩下的用lct维护
注意联通的方式是把把边看做点, 然后连接(所以加上n) ->link(u, i + n); link(v, i + n);
(由于我一直不理解怎么保证当前的a一定在路径上,所以这是自己yy的证明(可能有很大的bug,勿喷):当前的a如果不在(1,n)路径之中,但(1,n)已联通,那么最优值在之前已经被计算过,否则由于a是递增的,那么此时的a就是路径中最大的a)
下面是代码
/**************************************************************
Problem: 3669
User: cminus
Language: C++
Result: Accepted
Time:5104 ms
Memory:6128 kb
****************************************************************/
#include <cstdio>
#include <algorithm>
using namespace std;
#define l(x) ch[x][0]
#define r(x) ch[x][1]
#define kd(x) (r(fa[x]) == x)
#define setc(f, c, k) (ch[fa[c] = f][k] = c)
#define isRoot(x) (r(fa[x]) != x && l(fa[x]) != x)
const int N = ;
struct Edge{
int u, v, a, b;
inline void init(){
scanf("%d %d %d %d", &u, &v, &a, &b);
}
inline bool operator <(const Edge &rhs)const{
return a < rhs.a;
}
}e[];
int fa[N], ch[N][], rev[N], val[N], maxp[N], f[];
int INF = 0x7f7f7f7f;
inline void update(int x) {
maxp[x] = x;
if (val[maxp[x]] < val[maxp[l(x)]]) maxp[x] = maxp[l(x)];
if (val[maxp[x]] < val[maxp[r(x)]]) maxp[x] = maxp[r(x)];
}
inline void push(int x) {
if (rev[x] and x){
rev[x] = ;
if (l(x)) rev[l(x)] ^= , swap(l(l(x)), r(l(x)));
if (r(x)) rev[r(x)] ^= , swap(l(r(x)), r(r(x)));
}
}
inline void pushDown(int x) {
if (! isRoot(x)) pushDown(fa[x]);
push(x);
}
inline void rotate(int x) {
int y = fa[x], t = kd(x);
setc(y, ch[x][t^], t);
if (isRoot(y)) fa[x] = fa[y];
else setc(fa[y], x, kd(y));
setc(x, y, t^);
update(y); update(x);
}
inline void splay(int x){
pushDown(x);
while(! isRoot(x)){
if (! isRoot(fa[x]))
if (kd(x) == kd(fa[x])) rotate(fa[x]);
else rotate(x); rotate(x);
}
}
inline void access(int x){
int t = ;
while(x) {
splay(x);
r(x) = t; update(x);
t = x; x = fa[x];
}
}
inline void makeRoot(int x){
access(x); splay(x);
rev[x] ^= ; swap(l(x), r(x));
}
inline void link(int u, int v) { makeRoot(u); fa[u] = v; }
inline void cut(int u, int v){
makeRoot(u);
access(v); splay(v);
fa[u] = l(v) = ;
}
inline int query(int u, int v){
makeRoot(u);
access(v); splay(v);
return maxp[v];
}
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
int main(){
int n, m;
scanf("%d %d", &n, &m);
int ans = INF;
for (int i = ; i <= m; i++) e[i].init();
for (int i = ; i <= n; i++) f[i] = i;
sort(e + , e + m + );
for (int i = ; i <= m; i++){
int u = e[i].u, v = e[i].v, rt1 = find(u), rt2 = find(v);
val[i + n] = e[i].b; maxp[i + n] = i + n;
if (rt1 == rt2){
int p = query(u, v);
if (val[p] > e[i].b) cut(u, p), cut(v, p);
else continue;
}
else f[rt1] = rt2;
link(u, i + n); link(v, i + n);
if (find() == find(n)) ans = min(ans, val[query(, n)] + e[i].a);
}
printf("%d\n", ans == INF ? - : ans);
return ;
}
bzoj 3669: [Noi2014]魔法森林 (LCT & kruskal)的更多相关文章
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- bzoj 3669: [Noi2014] 魔法森林 LCT版
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)
传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...
- bzoj 3669: [Noi2014]魔法森林
bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...
- bzoj 3669: [Noi2014]魔法森林 动态树
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 363 Solved: 202[Submit][Status] ...
- bzoj 3669: [Noi2014]魔法森林 -- 动点spfa
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...
- [BZOJ 3669] [Noi2014] 魔法森林 【LCT】
题目链接:BZOJ - 3669 题目分析 如果确定了带 x 只精灵A,那么我们就是要找一条 1 到 n 的路径,满足只经过 Ai <= x 的边,而且要使经过的边中最大的 Bi 尽量小. 其实 ...
- bzoj 3669: [Noi2014]魔法森林(并查集+LCT)
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
随机推荐
- 统一操作系统 UOS 回应质疑 (独立思考)
统一操作系统 UOS 回应质疑 自从统一操作系统UOS正式版面向合作伙伴发布之后,小编就关注到网上对统一操作系统UOS众说纷纭.留意了近期网友们发表的评论: “又多了一个骗钱的国产操作系统” “从UO ...
- Verilog-case、casez和casex的区别
参考博客:https://www.cnblogs.com/guolongnv/articles/6906929.html 1.基本概念 1)?表示z,而不是“dont care” 2)区分: case ...
- matlab HW求法笔记
for i=1:9400 Sbox_out_11(i) = length(findstr(num2str(dec2bin(Sbox_out_1(i,:))),'1')); end
- 【Linux02】LInux初始入门
1.LInux操作系统发展与演变 ENIARC: CUP:运算器.控制器.寄存器.缓存 存储器:内存.RAM Input:指令+数据 Output:结果 程序:指令+数据 算法+数据结构 字节是 ...
- mysql 视图 触发器 存储过程 函数事务 索引
mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...
- django csrf 中间件
CSRF和中间件 CSRF使用 说明csrf存在cookie中 全局使用 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', ...
- laravel框架使用阿里短信接入
EG: accessKeyid和accessKeySecret还有模板ID.签名名称这几项必要参数自己去阿里云获取一.下载SDK和demo 下载并解压后 在laravel框架的app目录下创建libs ...
- php文件上传 form表单形式
1.php界面 <?php header( 'Content-Type:text/html;charset=utf-8 ');include_once("conn/conn.php&q ...
- [Arc068D/At2299] Card Eater - 结论
[Arc068D/At2299] 有一堆牌,每张牌上有一个数字. 每次可以取出其中 \(3\) 张,丢掉数字最大的和数字最小的牌,把中间那张再放回牌堆. 要求最后所有剩余牌上的数字互不相同,求最多能剩 ...
- 避免layui form表单重复触发submit绑定事件
个人博客 地址:http://www.wenhaofan.com/article/20180927002336 在使用以下代码监听lay-filter为editConfig的提交按钮后,当点击提交按钮 ...