传送门:here

简述题意:                                                                                           

给定一张$ n$个点,$ m$条边$ (2<=n,m<=5*10^5)$的无向连通图

有$ k(1<=k<=5*10^5)$次询问

每次询问一个边集$ S(\sum\limits_{i=1}^k|S_i|<=5*10^5)$,判断这些边能否共存于原图的某棵最小生成树上

并查集撤销上一次操作:                                                                      

不能像普通并查集一样路径压缩,因此只能按址合并

每次把size较小的接到size较大的下面

同时开个栈记录被接上去的点的标号

撤销上一次操作的时候直接把栈顶的标号的father重标成自己同时减小原father的size值即可

题解:                                                                                                 

先简化题意:假设每次询问的边集大小均为1

思考克鲁斯卡尔的原理

首先对所有边按边权从小到大排序

克鲁斯卡尔告诉我们一条当前可插入的边权最小的边,插入一定不会不优

因而一条边权为x的边可以在最小生成树内当且仅当把所有权值严格小于x的边插入生成树后加入这条边依然不会形成环

也就是说边权不同的边相互独立,从小到大贪心即可

因此我们把询问离线排序,从小到大判断每次询问对应的边可否插入,可插入则该次询问为YES且插入,否则该次询问一定为NO

如果有两条边边权相同怎么办?

直接检验不一定正确,因为前一条边不一定必选,而之前程序已经将其插入

因此需要撤销上一次并查集的合并操作,然后再检验下一条边

回到原题

我们知道边集大小不一定为1

依然按边权排序,在每条询问边标记询问标号

由于之前提到不同边权相互独立,因此只要某组询问的每一种边权对应的边可以全选,最终也一定可行

反之只要一个询问中有一条边不合法则不可行

因此像上面一样排序后从小到大扫即可

注意同一个询问的相同边权的边检验必须一起做,全部做完之后再一起撤销

因为在同一个询问里同一种边权是不独立的,必须全部插入后依然不形成环才可行

code:                                                                                                 

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rt register int
#define l putchar('\n')
#define ll long long
#define M 1000010
using namespace std;
inline ll read()
{
register ll x = ; char zf = ; char ch;
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
int i,j,k,m,n,x,y,z,cnt,la[M],fa[M],size[M],top,g=;
int ask(int x)
{
while(fa[x]!=x)x=fa[x];
return x;
}
void merge(int x,int y)
{
if(x==y)return;
if(size[x]>size[y])swap(x,y);la[++top]=x;
fa[x]=y;size[y]+=size[x];
}
void undo()
{
int La=la[top];
size[fa[La]]-=size[La];
fa[La]=La;top--;
}
struct ed
{
int x,y,z;
inline bool operator <(const ed s)const
{
return z<s.z;
}
}q[M]; struct query
{
int id,x,y,val;
inline bool operator <(const query s)const
{
if(val==s.val)return id<s.id;
return val<s.val;
}
}A[M];
int ans[M];
int main()
{
n=read();m=read();
for(rt i=;i<=n;i++)size[i]=,fa[i]=i;
for(rt i=;i<=m;i++)
{
x=read();y=read();z=read();
q[i]={x,y,z};
} k=read();
for(rt e=;e<=k;e++)
{
z=read();ans[e]=;
for(rt i=;i<=z;i++)
{
x=read();
A[++cnt]={e,q[x].x,q[x].y,q[x].z};
}
}
sort(q+,q+m+);
sort(A+,A+cnt+);
int qd=;
for(rt i=;i<=cnt;)
{
while(q[qd].z<A[i].val)
merge(ask(q[qd].x),ask(q[qd].y)),qd++; top=;
do
{ int p1=ask(A[i].x),q1=ask(A[i].y);
if(p1==q1)ans[A[i].id]=;
merge(p1,q1);
i++;
}while(A[i].val==A[i-].val&&A[i].id==A[i-].id);
while(top)undo();
}
for(rt i=;i<=k;i++)puts(ans[i]?"YES":"NO");
return ;
}

Codeforces891C(892E)的更多相关文章

  1. Codeforces891C. Envy

    $n \leq 5e5$,$m \leq 5e5$的无向边权图,$q \leq 5e5$个询问,每次问一系列边是否能同时存在于某棵最小生成树上. 一条边在最小生成树上,当比他小的边都加入后,加入他会使 ...

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

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

  3. Codeforces 892E Envy

    问题描述 小Q正在玩一个叠塔的游戏,游戏的目标是叠出尽可能高的塔.在游戏中,一共有n张矩形卡片,其中第i张卡片的 长度为a_i,宽度为b_i.小Q需要把所有卡片按一定顺序叠成一座塔,要求对于任意一个矩 ...

  4. REORG TABLESPACE on z/os

    这个困扰了我两天的问题终于解决了,在运行这个job时:总是提示 A REQUIRED DD CARD OR TEMPLATE IS MISSING NAME=SYSDISC A REQUIRED DD ...

  5. Neutron命令测试5

    jolin@jolin:/$ route -nKernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Iface ...

  6. Neutron命令测试4

    jolin@jolin:~$ route -nKernel IP routing tableDestination Gateway Genmask Flags Metric Ref Use Iface ...

随机推荐

  1. Django 配置QQ邮箱连接

    首先要在settings.py内进行配置 # 邮件服务配置文件 EMAIL_USE_SSL = True # 邮箱服务 EMAIL_HOST = 'smtp.qq.com' # 端口号 EMAIL_P ...

  2. 关于Java中扫描仪next()与nextLine()的区别

    首先,next()一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键.Tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后 ...

  3. python基础之文件表格读取

    实现功能:提取表格某一列的值. 所用库:xlrd 打开表格的函数 def open_excel_file(filename,sheet_num=0): xlsfile = filename book ...

  4. DAY2---Python---While循环,格式化输出,运算符,编码

    一.while循环 while 条件: 代码块(循环体) 流程:判断条件是否为真,如果是真,执行代码块.然后再次判断条件是否为真,如果为真继续执行代码块... 直到条件变成了假,退出循环 #死循环:永 ...

  5. 计算机基础:计算机网络-chapter4 网络层

    网络层的使用:如 ping,tracert,原理是ICMP 一.什么叫网络,网络层做什么,通过什么实现,这章的内容, 什么叫网络,实现这些需要做什么 将全世界范围内数以百万计的网络都互连起来,并且能够 ...

  6. sql server开发工具

    查询分析器的使用 SQL语言包含四个部分: 1.数据定义语言(DDL) : 例如 create, drop, alter等语句 2.数据操作语言(DML) : 例如 insert,delete, up ...

  7. 数据库基础SQL知识面试题二

    数据库基础SQL知识面试题二 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.选课系统SQL语法练习 course数据库中有以下四张表: •students表(学生表): si ...

  8. springcloud配置需要主要的地方

    Eureka服务端 注册中心 <!-- Eureka服务端 --> <dependency> <groupId>org.springframework.cloud& ...

  9. [NIO-2]通道和FileChannel

    通道是什么 通道式(Channel)是java.nio的第二个主要创新.通道既不是一个扩展也不是一项增强,而是全新的.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓 ...

  10. HDU - 6311 Cover(无向图的最少路径边覆盖 欧拉路径)

    题意 给个无向图,无重边和自环,问最少需要多少路径把边覆盖了.并输出相应路径 分析 首先联通块之间是独立的,对于一个联通块内,最少路径覆盖就是  max(1,度数为奇数点的个数/2).然后就是求欧拉路 ...