传送门

题目大意

给定 \(n\) 个点和 \(m\) 条边。每条边包含起点终点和两个精灵的最低限制,求最少需要携带的精灵数量。

题目解析

直接套 LCT 板子

将所有边按照进行升序排序,从小到大将边加入,在已经加入边的图上找路径的最大值,求出最大值和当前枚举的和用于更新全局的最小值答案。

为什么呢?因为要 \(a\),\(b\) 都满足才能通过某条边,所以结果必定为某条边的 \(a_i\) 或 \(b_i\), 因此可以固定 \(a\) 的信息来降低复杂度。即每次选取小于等于 \(a_i\) 大小的边去维护一条 \(1\) 到 \(n\) 的路径.

动态加边,维护最大值。

直接套 LCT 板子!!

虽然题目给出的是一张图, 但实际上只需要维护出一条从 \(1\) 到 \(n\) 的路径即可.因此当新加入一条边会使维护的树变成图时, 就需要去找到环, 若新边比环中最大值小, 那么将环中的最大边删去, 加入新边即可。

然后要注意用并查集(好像是卡常,因为 yxc 直接用的并查集)

利用动态树的特性快速求路径上的最大点权值。最后注意一下删边时的编号映射。(关于我忘了切断子树卡了半天15pts艹)

代码实现

#include <bits/stdc++.h>

#define int long long
#define rint register int #define endl '\n' using namespace std; const int N = 1e6 + 5; int n, m, p[N], stk[N], ans = 0x3f3f3f3f;
struct Edge
{
int x, y, a, b;
bool operator<(const Edge &t) const { return a < t.a; }
} e[N];
struct node
{
int s[2], p, v, mx, rev;
} tr[N]; int inline min(int a, int b)
{
return a < b ? a : b;
} int inline find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
} void inline pushrev(int u)
{
swap(tr[u].s[0], tr[u].s[1]);
tr[u].rev ^= 1;
return;
} void inline pushup(int u)
{
tr[u].mx = u;
int ll = tr[tr[u].s[0]].mx;
int rr = tr[tr[u].s[1]].mx;
if (tr[ll].v > tr[tr[u].mx].v)
{
tr[u].mx = ll;
}
if (tr[rr].v > tr[tr[u].mx].v)
{
tr[u].mx = rr;
}
return;
} void inline pushdown(int u)
{
if (tr[u].rev)
{
pushrev(tr[u].s[0]);
pushrev(tr[u].s[1]);
tr[u].rev = 0;
}
return;
} bool inline isroot(int u)
{
return tr[tr[u].p].s[0] != u && tr[tr[u].p].s[1] != u;
} void inline rotate(int x)
{
int y = tr[x].p;
int z = tr[y].p;
int k = tr[y].s[1] == x;
if (!isroot(y))
{
tr[z].s[tr[z].s[1] == y] = x;
}
tr[x].p = z;
tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
tr[x].s[k ^ 1] = y, tr[y].p = x;
pushup(y);
pushup(x);
return;
} void inline splay(int x)
{
int top = 0, r = x;
stk[++top] = r;
while (!isroot(r))
{
stk[++top] = r = tr[r].p;
}
while (top)
{
pushdown(stk[top--]);
}
while (!isroot(x))
{
int y = tr[x].p, z = tr[y].p;
if (!isroot(y))
{
if ((tr[z].s[1] == y) ^ (tr[y].s[1] == x))
rotate(x);
else
rotate(y);
}
rotate(x);
} return;
} void inline access(int x)
{
int z = x;
for (rint y = 0; x; y = x, x = tr[y].p)
{
splay(x);
tr[x].s[1] = y, pushup(x);
}
splay(z);
return;
} void inline makeroot(int x)
{
access(x);
pushrev(x);
return;
} int inline findroot(int x)
{
access(x);
while (tr[x].s[0])
{
pushdown(x);
x = tr[x].s[0];
}
splay(x);
return x;
} void inline split(int x, int y)
{
makeroot(x);
access(y);
return;
} void inline link(int x, int y)
{
makeroot(x);
if (findroot(y) != x)
tr[x].p = y;
return;
} void inline cut(int x, int y)
{
makeroot(x);
if (findroot(y) == x && tr[x].s[1] == y && !tr[y].s[0])
{
tr[y].p = tr[x].s[1] = 0;
pushup(x);
}
return;
} signed main()
{
cin >> n >> m; for (rint i = 1; i <= m; i++)
{
int x, y, a, b;
cin >> x >> y >> a >> b;
e[i] = {x, y, a, b};
} sort(e + 1, e + 1 + m); for (rint i = 1; i <= n + m; i++)
{
p[i] = i;
if (i > n)
tr[i].v = e[i - n].b;
tr[i].mx = i;
} for (rint i = 1; i <= m; i++)
{
int x = e[i].x;
int y = e[i].y;
int a = e[i].a;
int b = e[i].b; if (find(x) == find(y))
{
split(x, y);
int t = tr[y].mx;
if (tr[t].v > b)
{
cut(t, e[t - n].x);
cut(t, e[t - n].y);
link(i + n, x);
link(i + n, y);
}
}
else
{
p[find(x)] = find(y);
link(i + n, x);
link(i + n, y);
}
if (find(1) == find(n))
{
split(1, n);
ans = min(ans, a + tr[tr[n].mx].v);
}
} if (ans != 0x3f3f3f3f)
{
cout << ans << endl;
return 0;
} puts("-1"); return 0;
}

【NOI2014】 魔法森林---解题报告的更多相关文章

  1. 洛谷 P2387 [NOI2014]魔法森林 解题报告

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

  2. NOI2014魔法森林题解报告

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

  3. NOI2014 魔法森林

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

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

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

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

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

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

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

  7. BZOJ_3669_[Noi2014]魔法森林_LCT

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

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

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

  9. 「luogu2387」[NOI2014] 魔法森林

    「luogu2387」[NOI2014] 魔法森林 题目大意 \(n\) 个点 \(m\) 条边的无向图,每条边上有两个权值 \(a,b\),求从 \(1\) 节点到 \(n\) 节点 \(max\{ ...

  10. P2387 [NOI2014]魔法森林(LCT)

    P2387 [NOI2014]魔法森林 LCT边权维护经典题 咋维护呢?边化为点,边权变点权. 本题中我们把边对关键字A进行排序,动态维护关键字B的最小生成树 加边后出现环咋办? splay维护最大边 ...

随机推荐

  1. Libvirtd networks -- 为libvirtd 中虚拟机指定ip遇到的问题

    backgroup 为libvirtd 中虚拟机指定ip,操作如下: virsh --connect qemu:///system dumpxml vm01 | grep "mac addr ...

  2. 在Volo.Abp微服务中使用SignalR

    假设需要通过SignalR发送消息通知,并在前端接收消息通知的功能 创建SignalR服务 在项目中引用 abp add-package Volo.Abp.AspNetCore.SignalR 在Mo ...

  3. 安装 配置 正向 解析 DNS方法

    安装 配置 正向 解析 DNS方法 1,安装dhcp [root@localhost ~]#yum install bind* -y 2,关闭防火墙和selinux [root@localhost ~ ...

  4. Maven资源导出问题所需配置

    <!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> < ...

  5. [shell]在curl测试的data参数中引用变量

    在curl测试的data参数中引用变量 前言 在使用curl接口进行接口传参时,常会使用如下方法: #!/bin/bash url="http://192.168.0.10:8000/api ...

  6. IOS App内嵌H5 swiper 轮播出现卡顿白屏闪烁

    话说在前头:前端开发同学遇到这个问题不慌,因为接下来你要踩的坑我都帮你们踩完了,所以有了这一篇博客.希望能帮到你 轮播组件:swiper@4.5.1 (4x稳定的最后一个版本) 设备:ios版本15x ...

  7. Mybatis框架的搭建和基本使用

    本文总结最原始Mybatis框架的搭建和最基本使用(不涉及Spring框架体系). 1 依赖 首先,我们要引入Mybatis依赖: <dependency> <groupId> ...

  8. DASCTF 2023 & 0X401七月暑期挑战赛

    比赛只出了一道,小菜不是罪过-_- controlflow 这个题动调到底就行 for i in range(40): after_xor[i]=inp[i]^0x401 after_xor[i] + ...

  9. Redis系列20:LFU内存淘汰算法分析

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  10. 52条SQL语句,性能优化!

    52条SQL语句,性能优化! SQL语句性能优化 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2,应尽量避免在 where 子句中对 ...