[CF891C]Envy

news/2024/12/21 22:20:29/

题目

传送门 to luogu

思路

一开始以为是 l c t \tt lct lct 硬刚。结果看题解发现了更优美的解法!

注意到这样一个性质,所有的最小生成树,某个权值的边的数量相同。也就是说,无论你怎样选择,最终都会选出 c w c_w cw 条权值为 w w w 的边。

证明?不需要啊 😂 显然加入了权值不超过 w w w 的边之后,形成的连通块是不变的,无论怎么选边。那么权值为 w w w 的边的数量显然就是连通块大小作差。

所以把所有询问拆成小询问(毕竟连通性总是不变),然后排序。查询相当于把权值严格小于的全部加入并查集,然后加入这些边,看会不会形成环。回退就行。

代码

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long int_;
inline int readint(){int a = 0; char c = getchar(), f = 1;for(; c<'0'||c>'9'; c=getchar())if(c == '-') f = -f;for(; '0'<=c&&c<='9'; c=getchar())a = (a<<3)+(a<<1)+(c^48);return a*f;
}const int MaxN = 500005;struct UFS{int fa[MaxN], rnk[MaxN];vector< int > zxy; // fuckedvoid init(int n){for(int i=1; i<=n; ++i)fa[i] = i, rnk[i] = 1;zxy.clear();}inline int find(int a) const {for(; a^fa[a]; a=fa[a]);return a; // 直接跳到根}inline bool merge(int a,int b){int x = find(a), y = find(b);if(x == y) return false;if(rnk[x] > rnk[y]) swap(x,y);fa[x] = y, rnk[y] += rnk[x];zxy.push_back(x); return 1;}void stepBack(){int x = zxy.back();rnk[fa[x]] -= rnk[x];fa[x] = x, zxy.pop_back();}
};struct Edge{int a, b, v;bool operator < (const Edge &t) const {return v < t.v; // 按照 v 排序}
};
Edge ori[MaxN], e[MaxN];struct Query{int id, k; // 第 id 组询问,关于第 k 条边bool operator < (const Query &t) const {if(ori[k].v != ori[t.k].v)return ori[k].v < ori[t.k].v;return id < t.id; // id 相同放一块儿}
};
Query ask[MaxN];bool ans[MaxN]; UFS xyx;
int n, m, q, tot; // basic info
void solve(){int p = 1; // [1,p)的小询问已考虑for(int i=1,nxt; i<=m; i=nxt){/* 考虑边权为 e[i].v 的 */ ;while(p <= tot &&ori[ask[p].k].v == e[i].v){ans[ask[p].id] =ans[ask[p].id]&& xyx.merge(ori[ask[p].k].a,ori[ask[p].k].b);if(p <= tot && // 下一个换了个询问ask[p+1].id != ask[p].id)while(!xyx.zxy.empty())xyx.stepBack();++ p; // 无论如何,去下一个询问}/* 然后加入所有边权为 e[i].v 的 */ ;for(nxt=i; nxt<=m; ++nxt)if(e[nxt].v != e[i].v) break;else xyx.merge(e[nxt].a,e[nxt].b);xyx.zxy.clear(); // 这些边不回退}for(int i=1; i<=q; ++i)puts(ans[i] ? "YES" : "NO");
}int main(){n = readint(), m = readint();for(int i=1; i<=m; ++i){e[i].a = readint();e[i].b = readint();e[i].v = readint();ori[i] = e[i]; // 一个排序一个不}q = readint(), tot = 0;for(int i=1; i<=q; ++i){int lj = readint();while(lj --){ask[++ tot].id = i;ask[tot].k = readint();}ans[i] = true; // 先肯定}sort(ask+1,ask+tot+1);sort(e+1,e+m+1);xyx.init(n), solve();return 0;
}

http://www.ppmy.cn/news/420903.html

相关文章

envy【3】从 HAProxy 迁移到 Envoy 代理

文章目录 1.简介2. HAProxy 示例3. Frontend Configuration3.1 Envoy Listeners 4. Backend Configuration4.1 Envoy Filters and Clusters 5. 记录访问和错误6. 启动 1.简介 这个场景旨在支持你从 HAProxy 迁移到 Envoy Proxy。它将帮助您将以前对 HAProxy 的任何经验和理解应…

【代码重构】依恋情结(Feature Envy)和不合适的亲昵关系(Inappropriate Intimacy)-- 解决一个函数访问其它对象的数据比访问自己的数据更多的情况

依恋情结 ●症状和特点 一个方法访问另一个对象的数据多于访问它自己的数据。 ●问题产生的原因 在将字段移动到数据类之后&#xff0c;可能会出现这种情况。如果是这种情况&#xff0c;您可以将数据的操作也移到该类中。 ●解决方法 作为一个基本规则&#xff0c;如果事情…

为什么 kubernetes 环境要求开启 bridge-nf-call-iptables ?

文章目录 背景基于网桥的容器网络Service 同节点通信问题开启 bridge-nf-call-iptables我的环境netshoot 工具 参考 背景 Kubernetes 环境中&#xff0c;很多时候都要求节点内核参数开启 bridge-nf-call-iptables: sysctl -w net.bridge.bridge-nf-call-iptables1 参考官方文…

文件从 UNIX(LF) 批量改为 PC(CR+LF) ,编码格式保持源文件编码,CMD转换成功

如何把文件从 UNIX(LF) 批量改为 PC(CRLF) &#xff0c;编码格式保持源文件编码&#xff0c;通过电脑自带cmd 批量更改-1.0 chcp 65001 && FOR /F "tokens*" %f IN (dir /b D:\opt\output\DATA_FILE\20230531\*.DAT) DO type "D:\opt\output\DATA_FILE…

接口测试——接口测试文档

在执行接口测试前&#xff0c;测试人员肯定会先拿到开发给予的接口文档。测试人员可以根据这个文 档编写接口测试用例。所以&#xff0c;我们要先了解接口文档的主要构成及含义。 以购买开心产品项目接口文档为例&#xff0c;解析一下接口文档的组成。 完整的接口文档有公共信…

制作独特彩妆美女模特头像照片的PS教程

有时为了使图片更出众更出彩&#xff0c;我们需要在人物脸上做一些效果。前期拍摄时没给人物画彩妆。这时就需要我们用PS来实现了。最终效果 原图 一、新建一个图层&#xff0c;使用柔角笔刷并将颜色值设为#7e2224对眼睛内边缘进行涂抹&#xff0c;范围如图。修改图层模式为…

ps合成玫瑰花丛中漂亮美女照片

&#xff08;1&#xff09;把素材图打开。 &#xff08;2&#xff09;把人物 使用钢笔工具 扣出来。 如下所示&#xff1a; &#xff08;3&#xff09; 载入草丛笔刷&#xff0c;把颜色动态和传递去掉勾选&#xff0c;这2个选项可能会造成前后背景色反复更替 。 设置画笔&am…