给出一个 n 个点 m条边的无向图,每条边有边权,共 Q次询问,每次给出 \(k\)条边,问这些边能否同时在一棵最小生成树上。

Solution

所有最小生成树中某权值的边的数量是一定的

加完小于某权值的所有边后图的连通性是一样的

对于每个询问,每种权值分开考虑

对每个权值,加完小于这条边的权值后的所有边

然后判断这个权值在缩点后图上是否成环

因此需要跑一次 Kruskal 并且记录下对于每条边,加完权值小于它的所有边后,其两个端点所在的连通块编号

这样询问时只需要拿着并查集搞就可以了

#include <bits/stdc++.h>
using namespace std;
const int N = 1000005; struct edge {
int u,v,w,id,bu,bv;
bool operator < (const edge &b) const {
return w < b.w;
}
} e[N]; bool cmp(const edge &a, const edge &b) {
return a.id < b.id;
} int n,m,q,t1,t2,t3,f[N]; int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
void merge(int i,int j) {if(find(i)!=find(j)) f[find(i)]=find(j); } int solve(vector <edge> v) {
/*cout<<"solve"<<endl;
for(int i=0;i<v.size();i++) cout<<v[i].bu<<" "<<v[i].bv<<" "<<v[i].w<<endl;
cout<<"-----"<<endl;*/
map<int,int> mp;
for(int i=0;i<v.size();i++) mp[v[i].bu]++, mp[v[i].bv]++;
int ind=0;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
it->second = ++ind;
for(int i=0;i<v.size();i++) v[i].bu=mp[v[i].bu], v[i].bv=mp[v[i].bv];
for(int i=1;i<=ind;i++) f[i]=i;
int flag=1;
for(int i=0;i<v.size();i++) {
if(find(v[i].bu)==find(v[i].bv)) flag=0;
merge(v[i].bu,v[i].bv);
}
return flag;
} int main() {
ios::sync_with_stdio(false);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
e[i].id=i;
}
sort(e+1,e+m+1);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++) {
if(e[i].w != e[i-1].w) {
int pos=i;
while(e[pos].w == e[pos+1].w && pos<m) ++pos;
for(int j=i;j<=pos;j++) e[j].bu=find(e[j].u), e[j].bv=find(e[j].v);
}
merge(e[i].u,e[i].v);
}
scanf("%d",&q);
sort(e+1,e+m+1,cmp);
//for(int i=1;i<=m;i++) cout<<e[i].bu<<" "<<e[i].bv<<endl; for(int i=1;i<=q;i++) {
int tot;
scanf("%d",&tot);
vector <edge> v;
for(int j=1;j<=tot;j++) {
int tmp;
scanf("%d",&tmp);
v.push_back(e[tmp]);
}
sort(v.begin(),v.end());
v.push_back((edge){0,0,0});
int flag = 1;
for(int j=0;j<tot;j++) {
int pos=j;
while(v[j].w == v[j+1].w && pos<tot-1) ++pos;
vector <edge> vv;
for(int k=j;k<=pos;k++) vv.push_back(v[k]);
flag &= solve(vv);
j=pos;
}
if(flag) puts("YES");
else puts("NO");
}
}

[CF891C] Envy - Kruskal,并查集的更多相关文章

  1. TOJ 2815 Connect them (kruskal+并查集)

    描述 You have n computers numbered from 1 to n and you want to connect them to make a small local area ...

  2. Minimum Spanning Tree.prim/kruskal(并查集)

    开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...

  3. Connect the Campus (Uva 10397 Prim || Kruskal + 并查集)

    题意:给出n个点的坐标,要把n个点连通,使得总距离最小,可是有m对点已经连接,输入m,和m组a和b,表示a和b两点已经连接. 思路:两种做法.(1)用prim算法时,输入a,b.令mp[a][b]=0 ...

  4. hdu 1863 畅通工程(Kruskal+并查集)

    畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. POJ 3723 Conscription (Kruskal并查集求最小生成树)

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14661   Accepted: 5102 Des ...

  6. BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3545 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

  7. BZOJ3551 [ONTAK2010]Peaks加强版 kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3551 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

  8. 习题:过路费(kruskal+并查集+LCA)

    过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...

  9. HDU1863(Kruskal+并查集水题)

    https://cn.vjudge.net/problem/HDU-1863 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可). ...

随机推荐

  1. PMP--1.6 项目经理

    本节都是理论的东西,可以在管理没有思路的或者管理陷入困境的时候当做提升或解决问题的思路来看. 一.项目经理 1. 项目经理.职能经理与运营经理的区别 (1)职能经理专注于对某个职能领域或业务部门的管理 ...

  2. Spark应用开发调优要点总结

    调试Spark应用性能的时候,首先应该理解spark是如何工作以及你的spark应用需要何种类型的资源.比如说,机器学习相关的spark应用更依赖cpu计算能力,ETL应用更依赖I/O能力,以此进行有 ...

  3. C#实现的Table的Merge,以及实现Table的Copy和Clone

    C#实现的对两个Table进行Merge,两表必须存在至少一个公共栏位作为连接项,否则连接就失去了意义.如下是对两个table进行Merge的详细代码: private void button1_Cl ...

  4. 8.python内置模块之random模块简介

    Python中的random模块用于生成随机数. 常用的7个函数: 1.random.random():返回一个[0,1)之间的随机浮点值(双精度) 2.random.uniform(a,b):返回[ ...

  5. 微信小程序入门笔记-开通云开发(3)

    1.介绍 开发者可以使用云开发开发微信小程序.小游戏,无需搭建服务器,即可使用云端能力. 云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API ...

  6. 41.Python中加载静态文件

    在一个网页中,不仅仅只有一个html骨架,还需要css样式文件,js执行文件以及一些图片等.因此在DTL中加载静态文件时一个必须要解决的问题.在DTL中,使用static标签来加载静态文件.要使用st ...

  7. header.vue 调用变量,别的组件导入引用,组件方法事例实例

    <template> <div id="header"> <!-- 调用变量 --> <h1>{{ msg }}</h1> ...

  8. AT1219 歴史の研究[回滚莫队学习笔记]

    回滚莫队例题. 这题的意思大概是 设 \(cnt_i\) 为 l ~ r 这个区间 \(i\) 出现的次数 求\(m\) 次询问 求 l~r 的 max {\(a_i\) * \(cnt_i\)} \ ...

  9. Byte 一个字节的数据大小范围为什么是-128~127

    一个字节是8位,最高位是符号位,最高位为0则是正数.最高位为1则是负数 如果一个数是正数,最大数则为:01111111,转为十进制为127, 如果一个数是负数,按照一般人都会觉得是11111111,转 ...

  10. jQuery笔记(二)jQuery中DOM操作

    前言 本篇主要介绍DOM操作,在说DOM操作之前,首先我们应该熟悉DOM树,以一个例子为例来说明DOM树.首先看这段HTML代码.(本文后面的代码如果没有特别指出,都是针对下述HTML代码进行操作) ...