题解:P14610 [NWRRC 2025] Keys and Grates
Priestess_SLG · · 题解
900 AC,稍微写个题解。
考虑建图。先将数轴上所有点的坐标离散化,然后以
此时还存在钥匙
这个建图策略的正确性可以这样理解:对于一个门,先处理掉其和钥匙在
- 从
s 点方向连过来一条边。 - 从其对应的在另一侧的钥匙所对应的点连过来一条边。
该点确实会被
而对于另外一个钥匙
实现的时候不特判掉钥匙
namespace Loyalty
{
int a[N], b[N], f[N << 1], deg[N << 1];
vector<pair<int, int>> adj[N << 1];
inline void init() {}
inline void main([[maybe_unused]] int _ca, [[maybe_unused]] int atc)
{
int n, s, t;
cin >> n >> s >> t;
for (int i = 0; i <= 2 * n + 3; ++i)
adj[i].clear(), f[i] = -inf, deg[i] = 0;
vector<int> v = {s, t};
for (int i = 1; i <= n; ++i)
cin >> a[i] >> b[i], v.emplace_back(a[i]), v.emplace_back(b[i]);
sort(v.begin(), v.end()), v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 1; i <= n; ++i)
a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1,
b[i] = lower_bound(v.begin(), v.end(), b[i]) - v.begin() + 1;
s = lower_bound(v.begin(), v.end(), s) - v.begin() + 1;
t = lower_bound(v.begin(), v.end(), t) - v.begin() + 1;
for (int i = 1; i <= n; ++i)
adj[a[i]].emplace_back(b[i], abs(v[a[i] - 1] - v[b[i] - 1])), ++deg[b[i]];
for (int i = s - 1; i; --i)
adj[i + 1].emplace_back(i, abs(v[i] - v[i - 1])), ++deg[i];
for (int i = s; i < v.size(); ++i)
adj[i].emplace_back(i + 1, abs(v[i] - v[i - 1])), ++deg[i + 1];
queue<int> q;
q.emplace(s);
f[s] = 0;
while (q.size())
{
int t = q.front();
q.pop();
for (auto &[g, w] : adj[t])
{
f[g] = max(f[g], f[t] + w);
if (!--deg[g])
q.emplace(g);
}
}
cout << max(-1ll, f[t]) << '\n';
}
}