NC235745 拆路

题目链接

题目

题目描述

n 个城镇,城镇之间有 m 条道路相连,道路可以看成无向边。每一个城镇都有自己的一个繁荣度 vi ,一个城镇 u 受到的影响 p 是与u 直接或者间接相连的所有城镇中,繁荣度的最大值。一个城镇 u 与城镇 v 是被视为直接或者间接相连的,当且仅当 u=v 或者从 u 出发,可以沿着某些道路到达 v 。为了减少维护成本,现准备拆除其中的某一些路。具体来说,你需要维护以下两种操作:

  1. ​ 'Q' a,询问 a 城镇受到的影响 p
  2. ​ 'D' a b ,删除 a b 之间的道路。

输入描述

第一行输入两个整数 n,m(1n,m105) ,分别表示城镇的数量和道路的数量。第二行输入 n 个整数 v1,v2,...,vn(1vi109) ,分别表示每一个城镇的繁荣度。接下来 m 行,每行两个整数 u,v(1u,vn) ,表示城镇 u,v 之间有一条道路连接。保证不含有重边、自环。
接下来一行,输入一个整数 Q(1Q105) ,表示操作的个数。
接下来 Q 行,每行描述一个操作,以'Q' a(1an) 或者'D' a b(1a,bn) 的形式给出。对于删除操作,保证被删除的道路是存在的。

输出描述

对于每一个操作1,你都需要输出一个整数 p ,表示城镇 a 受到的影响。

示例1

输入

4 3
1 2 3 4
1 2
2 3
3 4
4
Q 1
D 2 3
Q 1
Q 3

输出

4
2
4

题解

知识点:并查集,离线。

普通并查集不支持撤销操作,这使得这道题难以解答,但转换一下思路,撤销的逆过程是新增,是并查集适用的操作,于是可以保存所有访问数据,离线逆向处理,再将答案保存最后输出即可。

时间复杂度 O((mlogn+q)logq+n)

空间复杂度 O(q+n+m)

代码

#include <bits/stdc++.h>
using namespace std;
int w[100007];
int u[100007], v[100007];
int du[100007], dv[100007];
set<pair<int, int>> s;
int fa[100007];
int ans[100007];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
int rx = find(x);
int ry = find(y);
if (w[rx] < w[ry]) fa[rx] = ry;
else fa[ry] = rx;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1;i <= n;i++) fa[i] = i;
for (int i = 1;i <= n;i++) cin >> w[i];
for (int i = 1;i <= m;i++) cin >> u[i] >> v[i];
int q;
cin >> q;
for (int i = 1;i <= q;i++) {
char op;
cin >> op;
if (op == 'Q') cin >> du[i];
else if (op == 'D') {
cin >> du[i] >> dv[i];
s.insert({ du[i],dv[i] });
s.insert({ dv[i],du[i] });
}
}
for (int i = 1;i <= m;i++)
if (s.find({ u[i],v[i] }) == s.end())
merge(u[i], v[i]);
for (int i = q;i >= 1;i--) {
if (dv[i]) merge(du[i], dv[i]);
else ans[i] = w[find(du[i])];
}
for (int i = 1;i <= q;i++) {
if (ans[i]) cout << ans[i] << '\n';
}
return 0;
}
posted @   空白菌  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示