正题

题目链接:https://www.luogu.com.cn/problem/CF891C


题目大意

\(n\)个点\(m\)条边的一张无向联通图,每次询问一个边集能否同时出现在同一棵最小生成树上。

\(1\leq n,m,q,w_i,\sum k\leq 5\times 10^5\)


解题思路

考虑\(Kruskal\)的做法,每次找一条最小的边然后判断是否能够加入最小生成树。

考虑到边权相同的边可以任意排序,我们把它称之为同一层的边,并且无论任意排序最后产生的图的连通情况都不会改变。

我们把一个询问的边按照边分层,那么每层的边都合法这个询问就合法。

然后对于一个询问同一层的边,直接离线,然后把前面的层都加入之后,再把所有这些询问边加入判断是否合法即可。因为前面的层不能重新插,所以做完要撤销回去。

时间复杂度:\(O(n\log n)\)(全部同级的话)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=5e5+10;
struct node{
int x,y,w;
}e[N],b[N];
int n,m,Q,k,cnt,fa[N],dep[N],mk[N];
bool ans[N];
vector<node> q[N];
vector<int> h[N];
stack<node> cl;
int find(int x)
{return (fa[x]==x)?x:find(fa[x]);}
void unionn(int x,int y){
if(dep[x]>dep[y])swap(x,y);
cl.push((node){x,y,dep[y]});
fa[x]=y;dep[y]=max(dep[y],dep[x]+1);
return;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
scanf("%d",&Q);
for(int i=1;i<=Q;i++){
int k;scanf("%d",&k);
for(int j=1,x;j<=k;j++)
scanf("%d",&x),b[j]=e[x];
sort(b+1,b+1+k,cmp);ans[i]=1;
for(int j=1;j<=k;j++){
if(b[j].w!=b[j-1].w)
++cnt,h[b[j].w].push_back(cnt),mk[cnt]=i;
q[cnt].push_back(b[j]);
}
}
sort(e+1,e+1+m,cmp);
for(int i=1;i<=n;i++)fa[i]=i;
for(int l=1,r=1;l<=m;l=r+1){
while(e[r+1].w==e[l].w)r++;
int w=e[l].w;
while(!cl.empty())cl.pop();
for(int j=0;j<h[w].size();j++){
int p=h[w][j];
for(int i=0;i<q[p].size();i++){
int x=q[p][i].x,y=q[p][i].y;
x=find(x);y=find(y);
if(x==y){ans[mk[p]]=0;break;}
unionn(x,y);
}
while(!cl.empty()){
node x=cl.top();cl.pop();
dep[x.y]=x.w;fa[x.x]=x.x;
}
}
for(int i=l;i<=r;i++){
int x=find(e[i].x),y=find(e[i].y);
if(x==y)continue;
unionn(x,y);
}
}
for(int i=1;i<=Q;i++)
if(ans[i])puts("YES");
else puts("NO");
return 0;
}

CF891C-Envy【可撤销并查集】的更多相关文章

  1. bzoj2049 线段树 + 可撤销并查集

    https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...

  2. CodeForces892E 可撤销并查集/最小生成树

    http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki​ 条边,问这些边 ...

  3. BZOJ4358: permu(带撤销并查集 不删除莫队)

    题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...

  4. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

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

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

  6. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  7. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

  8. 算法笔记--可撤销并查集 && 可持久化并查集

    可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...

  9. 2019牛客第八场多校 E_Explorer 可撤销并查集(栈)+线段树

    目录 题意: 分析: @(2019牛客暑期多校训练营(第八场)E_Explorer) 题意: 链接 题目类似:CF366D,Gym101652T 本题给你\(n(100000)\)个点\(m(1000 ...

  10. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...

随机推荐

  1. mongoose 更新数据时不验证数据(忽略设定的集合规则)的问题

    问题: mongoose 更新数据时不验证数据(忽略设定的集合规则)的问题 参考: http://www.mongoosejs.net/docs/api.html#updateone_updateOn ...

  2. 教你IO流来便利电脑磁盘所有文件,把图片放到一个文件夹里(会发现什么不可告人的密码)

    一.需求 我要把C盘下面的所有图片都拿出来,放到一个新文件夹中.今天小编一身正气,看看有没有什么意外发现!!学会看看自己的盘,悄悄的哦!!! 二.代码展示(运行时间可能有点长) import java ...

  3. 【linux】tail 命令详解

    转自:https://www.cnblogs.com/fps2tao/p/7698224.html Linux命令:显示文件结尾 Head/Tail head 与 tail 就像它的名字一样的浅显易懂 ...

  4. linux的一般命令------附加

    1.cat /etc/redhat-release             查看linux版本 2. ps -ef|grep ssh                        查看进程在不在 3. ...

  5. 从eclipse转idea不适记录【持续更新】

    使用eclipse和idea时,快捷键对比 从一些最扎心的开始: 关于print一类的打印输出:System.out.println()补全 idea中可以sout.souf.serr:分别对应out ...

  6. JDBC中级篇(MYSQL)——处理文件(BLOB)

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package b_blob_clob; import java.io.FileInputStream; import java.i ...

  7. Promise.resolve()与Promise

    //Promise.resolve()和Promise.reject()常用来生成已经被决议为失败或者成功的promise案例 //Promise.reject()简单一些,不管传给它什么值,它决议为 ...

  8. VS2017 添加预定义宏

    project_name[right click] -> Properties -> C/C++ -> Preprocessor -> Preprocessor Definit ...

  9. IMO 2021 第一题题解及相关拓展问题分析

    IMO 2021 第 1 题: 设整数 n ≥ 100.伊凡把 n, n + 1, ..., 2n 的每个数写在不同的卡片上.然后他将这 n + 1 张卡片打乱顺序并分成两堆.证明:至少有一堆中包含两 ...

  10. 设置 ajax 同步获取数据

    问题 在处理DataTable的render进行列表渲染的时候发现通过ajax发送请求,返回的值并不正确. {"data":"id","render& ...