CF892E Envy[最小生成树]
题意:有一张 $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[最小生成树]的更多相关文章
- CF891C Envy 最小生成树/虚树
正解:最小生成树/虚树 解题报告: 传送门! sd如我就只想到了最暴力的想法,一点儿优化都麻油想到,,,真的菜到爆炸了QAQ 然后就分别港下两个正解QAQ 法一,最小生成树 这个主要是要想到关于最小生 ...
- 【CF891C】Envy(最小生成树)
[CF891C]Envy(最小生成树) 题面 Codeforces 洛谷 题解 考虑\(MST\)的构建过程,对于所有权值相同的边一起考虑. 显然最终他们连出来的结果是固定的. 把连边改为把联通块联通 ...
- 【CF891C】Envy 离线+最小生成树
[CF891C]Envy 题意:给你一个图,边有边权,每次询问给你一堆边,问你是否存在一个原图的最小生成树包含给出的所有边.n,m,q<=100000 题解:思路很好的题. 首先有一个非常重要的 ...
- CodeForces - 891C: Envy(可撤销的并查集&最小生成树)
For a connected undirected weighted graph G, MST (minimum spanning tree) is a subgraph of G that con ...
- CF891C Envy【最小生成树】
题目链接 我们知道,根据Kruskal的贪心,对于最小生成树,每一种权值的边数是一样的,而且如果将\(\leq x\)的边做最小生成树,合法方案的联通性是一样的.所以我们可以对于所有边分开考虑. 对于 ...
- Codeforces 891C Envy
Envy 感觉这种最小生成树上的啥题都差不多的解法.. #include<bits/stdc++.h> #define LL long long #define fi first #def ...
- Codeforces 891C Envy(MST + 并查集的撤销)
题目链接 Envy 题意 给出一个连通的无向图和若干询问.每个询问为一个边集.求是否存在某一棵原图的最小生成树包含了这个边集. 考虑$kruskal$的整个过程, 当前面$k$条边已经完成操作的时 ...
- 代码的坏味道(18)——依恋情结(Feature Envy)
坏味道--依恋情结(Feature Envy) 特征 一个函数访问其它对象的数据比访问自己的数据更多. 问题原因 这种气味可能发生在字段移动到数据类之后.如果是这种情况,你可能想将数据类的操作移动到这 ...
- 最小生成树(Kruskal算法-边集数组)
以此图为例: package com.datastruct; import java.util.Scanner; public class TestKruskal { private static c ...
随机推荐
- 关于c调用lua 对‘luaL_newstate()’未定义的引用的问题解决办法
#include <string.h>#include "lua.h"#include "lauxlib.h"#include "lual ...
- 第三次Java实验报告
Java实验报告 班级 计科二班 学号20188437 姓名 何磊 完成时间 2019/9/22 评分等级 实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档 ...
- Kafka主题体系架构-复制、故障转移和并行处理
本文讨论了Kafka主题的体系架构,讨论了如何将分区用于故障转移和并行处理. Kafka主题,日志和分区 Kafka将主题存储在日志中.主题日志分为多个分区.Kafka将日志的分区分布在多个服务器或磁 ...
- C#常见面试题(一)——try-catch-finally-return
面试常会被问及try-catch-finally,现在做一下总结: 第一.不管有没有出现异常,finally块中代码都会执行. 第二.finally 代码块中不能有return. 第三.如果try 或 ...
- 华为设备ACL与NAT技术
ACL 访问控制列表(Access Control Lists),是应用在路由器(或三层交换机)接口上的指令列表,用来告诉路由器哪些数据可以接收,哪些数据是需要被拒绝的,ACL的定义是基于协议的,它适 ...
- Qt Model/View理解(二)---构造model(细心研读,发现超简单,Model就是做三件事:返回行数量、列数量、data如何显示。然后把model与view联系起来即可,两个例子都是如此)good
数据是一个集合,显示也是一个集合.例如一篇<西游记>的文章,所有的文字就是数据集合,展示方式就是显示的集合,可以以书本的形式,也可以以电纸书的形式,更可以用视频的方式展现. 下面是将一个二 ...
- O051、Create Volume 操作 (Part II)
参考https://www.cnblogs.com/CloudMan6/p/5612147.html 1.cinder-scheduler 也会启动一个工作流 volume_create_ ...
- python增量爬虫
import pymysql def insert_db(db_table, issue, time_str, num_code): host = '127.0.0.1' user = 'root' ...
- springBoot2.x 支持跨域请求配置
提供三种配置方式: 1.配置过滤器,实现 WebMvcConfigurer接口(springboot2.x的方式) @Configuration public class GlobalCorsConf ...
- PostgreSQL 初学常用实用命令
常用命令 psql -h ip -p port -U user -d dbName 数据库 \dt(当前数据库所有表) \l(所有数据库) \c(切换数据库) \d 表名(查看表结构) table \ ...