解题思路


题目大意:

就是给你一个无向图,每个点都有一个权值,和qqq次询问
每次询问有两种操作

  • 1 x:就询问从x点出发,能访问到的最大权值是多少,并把最大权值那个点的权值设置为0
  • 2 x:就是删除第xxx条边

解题思考

  1. 首先我一开始想正着做但是很麻烦
  2. 我考虑每个要被删除的边,它要是对答案有影响那么它肯定是破环了连通性,我们可以先求个生成树,维护好连通性
  3. 那么我们先把没有要删除的边先求一个生成树,因为这些边是不会被删除的连通性不会变了,然后把,删除的边,按照逆序,为了方便并查集维护生成树时候撤销
  4. 我们用setsetset去维护每个块,合并的时候启发式合并就好了
  5. 这里有个小tiptiptip是就是每次访问过的点就在setsetset里面永久删除,因为它变成0了,永远不可能是答案了
  6. 那么我们就是对所有点开个setsetset

AC code

#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 600010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {read(first);read(args...);
}
int n, m, q;
bool col[maxn];
vector<PII> ask, edge, last;
bool vis[maxn];
int fa[maxn], siz[maxn];
set<PII>stk[maxn];
vector<PII> tmp; int find(int p) {if(p == fa[p]) return p;return find(fa[p]);
}
inline void done(PII v) {int x = find(v.first),y = find(v.second);if(x == y ) {tmp.push_back(make_pair(-1,-1)); return;}if(siz[x] > siz[y]) swap(x,y);   tmp.push_back(make_pair(x,y));set<PII>::iterator it = stk[x].begin();// 启发式插入for(;it != stk[x].end(); ++ it) {stk[y].insert(*it);}fa[x] = y;              siz[y] += siz[x];
}inline void undone() {PII z = tmp.back();  tmp.pop_back();if(z.first == -1) return;   set<PII>::iterator it = stk[z.first].begin();for(;it != stk[z.first].end();) {if(col[(*it).second]) {// 只把永远不会出现的数删掉set<PII>::iterator ittmp = it;it ++;stk[z.first].erase(ittmp);}else {stk[z.second].erase(*it);// 从大集合里面删除it ++;}}fa[z.first] = z.first;        siz[z.second] -= siz[z.first];
}int main() {IOS;cin >> n >> m >> q;for(int i = 1; i <= n; ++ i) {int v;cin >> v;stk[i].insert({v,i});}for(int i = 0; i < m; ++ i) {int u, v;cin >> u >> v;edge.push_back({u,v});}for(int i = 0; i < q; ++ i) {int op, v;cin >> op >> v;ask.push_back({op,v});if(op == 2) vis[v-1] = 1, last.push_back(edge[v-1]);}for(int i = 1; i <= n; ++ i) fa[i] = i, siz[i] = 1;for(int i = 0; i < m; ++ i) {if(vis[i]) continue;done(edge[i]);}for(int i = last.size()-1; i >= 0; -- i) done(last[i]);for(int i = 0; i < q; ++ i) {int op = ask[i].first, v = ask[i].second;if(op == 2) undone();else {v = find(v);if(stk[v].empty()) cout << "0\n";else {cout << (*stk[v].rbegin()).first << endl;auto it = *stk[v].rbegin();col[it.second] = 1;stk[v].erase(it);//   cout << it.second << " = v " << endl;}}}return 0;
}

图论 + 并查集 ----最小生成树重构图 + 可撤销并查集 + set启发式合并 时间线上的离线求解 D. Graph and Queries相关推荐

  1. 图论8 并查集深入解析——边带权并查集和拓展域并查集和最小生成树

    我们先复习一下并查集的基本知识. 并查集的三个操作:查询,初始化,合并:并查集的结构:操作方法以及代码:路径压缩优化(详见<图论7 弗洛伊德&并查集算法详解>). 补充一下,并查集 ...

  2. 【挑战程序设计】- 2.5 图论(最短路、最小生成树)

    2.5 图论(最短路.最小生成树) 文章目录 2.5 图论(最短路.最小生成树) 2.5.1 定义们 2.5.2 图的表示 2.5.3 图的搜索 2.5.4 最短路问题 单源1:bellman-for ...

  3. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

  4. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  5. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  6. 【带你重拾Redis】Redis 哨兵集群实现高可用

    Redis 哨兵集群实现高可用 哨兵的介绍 sentinel,中文名是哨兵.哨兵是 Redis 集群架构中非常重要的一个组件,主要有以下功能: 集群监控:负责监控 Redis master 和 sla ...

  7. 2020CCPC(长春) - Ragdoll(启发式合并+带权并查集)

    题目大意:初始时给出 n 个集合,每个集合中都包含有一个数字,现在要求执行 m 次操作,每次操作分为下列三种类型: 1 x y:在 x 位置新建一个集合,并且放置一个数字 y 2 x y:合并集合 x ...

  8. bzoj 36733674 可持久化并查集加强版(可持久化线段树+启发式合并)

    CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...

  9. 洛谷P7518:宝石(倍增、可撤销并查集)

    解析 算法一 定义 upx,kup_{x,k}upx,k​ 为节点 xxx 从自己的颜色所在位置在返祖链上往后跳 2k2^k2k 个颜色到达的节点. 可以像倍增一样的求解. 这样对于一次询问 (s,t ...

最新文章

  1. POJ1679 Luogu4180 次小生成树
  2. [OpenGL ES 03]3D变换:模型,视图,投影与Viewport
  3. 【2018ACM山东省赛 - E】Sequence(树状数组,思维,优化)
  4. 20sccm_SCCM 2012安装图解教程(一步一步详细步骤)
  5. 机器人合金礼包_《Apex英雄》福利twitch礼包领取详细攻略,1机器人皮肤+5个包!...
  6. WordPress 主题教程 #5:主循环
  7. egg前面加什么,egg前加a还是an?
  8. Magic Odd Square 思维
  9. DEM高程数据下载方法
  10. 超详细|开关电源电路图及原理讲解
  11. 关于zblog模板当中标签、相关文章调用应该怎么来写
  12. 刘宇凡:一棵树给我的真理
  13. RGB(三色)灯配置常用颜色数据,用法讲解,基于C语言的程序讲解,七彩渐变程序讲解
  14. 微信公众平台版面设计需要服务器,微信公众平台丨排版的基本原则
  15. Spring Boot多模块项目打包
  16. 肖战真的没我帅!我自己写的Python颜值检测说的!
  17. JS 中 replace 和 replaceAll 的区别?
  18. python文件打包成之pyinstaller使用
  19. 地理坐标系_GCS汇总
  20. 【环境问题】Anaconda-Navigator 更新后无法打开,运行出现UnicodeDecodeError的解决方案

热门文章

  1. 爬虫之selenium标签页的切换
  2. ping不通是不是就真不通?
  3. 大TTT需要复习的课件PPT以及大作业完成链接
  4. PyTorch深度学习训练可视化工具tensorboardX
  5. 浅谈深度学习图像分割
  6. 视频程式化的基于帧差异的时间损失
  7. 【从零学习OpenCV 4】安装过程中问题解决方案
  8. 任务调度器leetcode621
  9. 混合云备份利用自定义Workflow保护MySQL的实践
  10. FBI很气愤:黑了CIA的熊孩子又回来了