题意:有一张 $n$ 个点$ m $条边的连通图。有$Q$ 次询问。每次询问给出 $k[i]$ 条边,问这些边能否同时出现在一棵最小生成树上。$n,m,Q,\sum k\le 500000$。


这题利用到了最小生成树的一个性质,可以结合我记的最小生成树笔记。在加入所有权值前$i-1$大的边后,目前的权值第$i$大的一些边不管怎么加,连通性都是一样的,也就是连通块内的点集都是一样的,只不过有一些剩下的边或者连接两个块内点的边不合法罢了。于是可以在kruskal的时候先处理出对于每条边,他连接的两个连通块是什么(以当时的角度记录块上并查集祖先)。然后处理询问的时候,排序后对于权值相同的边,用并查集判断他们连接的连通块是否有环,即合不合法即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=5e5+;
int n,m,q,k;
struct thxorz{
int u,v,w,id;
inline bool operator <(const thxorz&A){return w<A.w;}
}e[N];
struct stothx{int fx,fy,w;}g[N];
int anc[N];
int find_anc(int x){return x==anc[x]?x:anc[x]=find_anc(anc[x]);} inline void Kruskal(){
sort(e+,e+m+);
for(register int i=;i<=n;++i)anc[i]=i;
for(register int i=,st=;i<=m;++i)if(e[i].w^e[i+].w){
for(register int j=st;j<=i;++j)
g[e[j].id].fx=find_anc(e[j].u),g[e[j].id].fy=find_anc(e[j].v);//dbg(e[j].id),dbg2(g[e[j].id].fx,g[e[j].id].fy);
for(register int j=st;j<=i;++j)
anc[find_anc(g[e[j].id].fx)]=find_anc(g[e[j].id].fy);
st=i+;
}
}
int a[N],vis[N],cnt;
inline bool cmp(int a,int b){return g[a].w<g[b].w;}
inline void Query(){
read(k);for(register int i=;i<=k;++i)read(a[i]);a[k+]=;
sort(a+,a+k+,cmp);
for(register int i=,st=;i<=k;++i)if(g[a[i]].w^g[a[i+]].w){
for(register int j=st;j<=i;++j){//dbg(a[j]);
int fx=find_anc(g[a[j]].fx),fy=find_anc(g[a[j]].fy);//dbg2(fx,fy);
if(fx^fy)anc[fx]=fy,vis[++cnt]=fx;
else{while(cnt)anc[vis[cnt]]=vis[cnt],--cnt;puts("NO");return;}
}
st=i+;
while(cnt)anc[vis[cnt]]=vis[cnt],--cnt;
}
puts("YES");
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=;i<=m;++i)read(e[i].u),read(e[i].v),g[i].w=read(e[i].w),e[i].id=i;
Kruskal();
for(register int i=;i<=n;++i)anc[i]=i;
read(q);while(q--)Query();
return ;
}

总结:要理解kruskal本质和其性质,从而进行改造,注意连通块性质。

CF892E Envy[最小生成树]的更多相关文章

  1. CF891C Envy 最小生成树/虚树

    正解:最小生成树/虚树 解题报告: 传送门! sd如我就只想到了最暴力的想法,一点儿优化都麻油想到,,,真的菜到爆炸了QAQ 然后就分别港下两个正解QAQ 法一,最小生成树 这个主要是要想到关于最小生 ...

  2. 【CF891C】Envy(最小生成树)

    [CF891C]Envy(最小生成树) 题面 Codeforces 洛谷 题解 考虑\(MST\)的构建过程,对于所有权值相同的边一起考虑. 显然最终他们连出来的结果是固定的. 把连边改为把联通块联通 ...

  3. 【CF891C】Envy 离线+最小生成树

    [CF891C]Envy 题意:给你一个图,边有边权,每次询问给你一堆边,问你是否存在一个原图的最小生成树包含给出的所有边.n,m,q<=100000 题解:思路很好的题. 首先有一个非常重要的 ...

  4. CodeForces - 891C: Envy(可撤销的并查集&最小生成树)

    For a connected undirected weighted graph G, MST (minimum spanning tree) is a subgraph of G that con ...

  5. CF891C Envy【最小生成树】

    题目链接 我们知道,根据Kruskal的贪心,对于最小生成树,每一种权值的边数是一样的,而且如果将\(\leq x\)的边做最小生成树,合法方案的联通性是一样的.所以我们可以对于所有边分开考虑. 对于 ...

  6. Codeforces 891C Envy

    Envy 感觉这种最小生成树上的啥题都差不多的解法.. #include<bits/stdc++.h> #define LL long long #define fi first #def ...

  7. Codeforces 891C Envy(MST + 并查集的撤销)

    题目链接  Envy 题意  给出一个连通的无向图和若干询问.每个询问为一个边集.求是否存在某一棵原图的最小生成树包含了这个边集. 考虑$kruskal$的整个过程, 当前面$k$条边已经完成操作的时 ...

  8. 代码的坏味道(18)——依恋情结(Feature Envy)

    坏味道--依恋情结(Feature Envy) 特征 一个函数访问其它对象的数据比访问自己的数据更多. 问题原因 这种气味可能发生在字段移动到数据类之后.如果是这种情况,你可能想将数据类的操作移动到这 ...

  9. 最小生成树(Kruskal算法-边集数组)

    以此图为例: package com.datastruct; import java.util.Scanner; public class TestKruskal { private static c ...

随机推荐

  1. win10下查看进程,杀死进程

    参考链接:https://blog.csdn.net/qq_36819098/article/details/80262482

  2. 常用小功能js函数-函数防抖

    函数防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时.这个我经常用到/** * 函数防抖 * fun 需要延时执行的函数 * delayTime 延时时间 * **/export ...

  3. [转帖]nginx配置ssl证书实现https访问

    https://www.cnblogs.com/tianhei/p/7726505.html 今天就是如此处理的 感觉挺不错的. 一,环境说明 服务器系统:ubuntu16.04LTS 服务器IP地址 ...

  4. odoo10实现单点登陆绕过登陆集成页面

    背景:由于需要集成odoo平台在其他页面,需要绕开登陆. 解决办法:开辟一个自动登陆的路由用与集成页面. 1.修改web模块中controller/main.py文件,在class名字为Home中添加 ...

  5. Kafka主题体系架构-复制、故障转移和并行处理

    本文讨论了Kafka主题的体系架构,讨论了如何将分区用于故障转移和并行处理. Kafka主题,日志和分区 Kafka将主题存储在日志中.主题日志分为多个分区.Kafka将日志的分区分布在多个服务器或磁 ...

  6. table+ajax加载数据

    //ajax加载notice $(function() { //${pageContext.request.contextPath}/ /** var res = [ {noticeTitle:'必答 ...

  7. VerilogHDL学习

    No.1 Verilog HDL程序结构 Verilog 描述硬件的基本设计单元是模块 module 复杂的电子电路构建主要是通过模块之间的相互连接调用来实现的,在Verilog中将模块包含在关键字 ...

  8. 今天测试大商创,遇到了 upstream sent too big header while reading response header from upstream

    今天在测试大商创后台系统时,打开店铺结算,查看店铺对应的订单列表时,该列表自动跳转到502,查看线上和测试环境都能正常打开,唯独我的电脑上打开是502, 查询nginx的error.log日志,记录了 ...

  9. 201709-3 JSON查询

    问题描述 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,可以用来描述半结构化的数据.JSON 格式中的基本单元是值 (value),出于简化的目的本题 ...

  10. tensorflow零起点快速入门(3)

    创造并运行数据 创造了-3到3的32条数据,然后通过sess.run获取并显示输出数据. x=tf.linspace(-3.0,3.0,32) print(x) sess=tf.Session() r ...