传送门

题目大意

给定 \(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. debian 防火墙命令 nft

    参考链接:nftables # which nft /usr/sbin/nft # dpkg -S /usr/sbin/nft nftables: /usr/sbin/nft # dpkg -L nf ...

  2. Postgresql: 常用配置

    允许远程链接postgresql 要允许 PostgreSQL 数据库允许远程连接,需要进行以下配置步骤: 打开 PostgreSQL 的主配置文件 postgresql.conf.通常,该文件位于以 ...

  3. html表格基本标签

    1.<table>表签 <table>...</table>标签用于在html文档中后创建表格.它包含表名和表格本身内容的代码. 2.<tr>标签 &l ...

  4. 【go语言】2.4.3 Go Modules

    Go Modules 是 Go 语言的官方依赖管理工具,自 Go 1.11 版本开始引入.它解决了 Go 语言在依赖管理上的一些问题,如版本控制.依赖隔离等. 初始化一个新的模块 你可以使用 go m ...

  5. python2.7源码安装方式

    安装python2.7 下载Python 2.7, 下载地址 解压安装 tar -xzvf Python-2.7.15.tgz cd Python-2.7.15 ./configure --prefi ...

  6. 【算法】用c#实现德州扑克卡牌游戏规则

    德州扑克是一种牌类游戏,可多人参与,它的玩法是,玩家每人发两张底牌,桌面依次发5张公共牌,玩家用自己的两张底牌和5张公共牌自由组合,按大小决定胜负. 使用c#完成功能Hand()以返回手牌类型和按重要 ...

  7. quarkus依赖注入之九:bean读写锁

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<quarkus依赖注入> ...

  8. 从浅入深了解.NET Core MVC 2.x全面教程【第二章】

    二.Logging 1.诊断中间件 命名空间:Microsoft.AspNetCore.Diagnostics 报告信息并处理异常 2.诊断中间件 UseDeveloperExceptionPage: ...

  9. 何时使用MongoDB而不是MySql

    什么是 MySQL 和 MongoDB MySQL 和 MongoDB 是两个可用于存储和管理数据的数据库管理系统.MySQL 是一个关系数据库系统,以结构化表格格式存储数据.相比之下,MongoDB ...

  10. AVR汇编(六):分支指令

    AVR汇编(六):分支指令 分支指令用于改变程序的执行流,分为无条件分支和条件分支两类. 无条件分支指令 JMP JMP 指令用于无条件跳转,类似于C中的 goto 关键字, JMP 指令的跳转范围为 ...