「CF891C」Envy
Posted zsbzsb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CF891C」Envy相关的知识,希望对你有一定的参考价值。
传送门
Luogu
解题思路
考虑最小生成树的几个性质:
- 所有最小生成树中边权相等的边的条数相等
- 在任意一颗最小生成树中,边权相等的边所联通的点集一定
那么我们考虑把边权相等的边单独拿出来考虑。
每次把并查集恢复到加边前的状态,然后再判断这些边加进去会不会形成环即可。
PS. 恢复并查集时,可以考虑求出每一条边在 ( ext{Kruskal}) 的过程中,将要被加入时两端点所在联通块。
细节注意事项
- 有点难实现,要有耐心
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
const int _ = 500010;
int fa[_], siz[_];
inline void init(int n) { for (rg int i = 1; i <= n; ++i) fa[i] = i; }
inline int findd(int x) { return fa[x] == x ? x : fa[x] = findd(fa[x]); }
inline void merge(int x, int y) { fa[findd(x)] = findd(y); }
int n, m, q;
struct edge{ int x, y, val, id, tx, ty; }g[_], e[_];
inline bool cmp(const edge& x, const edge& y) { return x.val < y.val; }
inline bool Cmp(const edge& x, const edge& y) { return x.id < y.id; }
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n), read(m);
for (rg int i = 1; i <= m; ++i)
read(g[i].x), read(g[i].y), read(g[i].val), g[i].id = i;
init(n), sort(g + 1, g + m + 1, cmp);
for (rg int i = 1; i <= m; ) {
int j = i;
do {
g[j].tx = findd(g[j].x);
g[j].ty = findd(g[j].y);
++j;
} while (j <= m && g[j].val == g[i].val);
while (i < j) {
while (findd(g[i].x) == findd(g[i].y) && i < j) ++i;
if (i < j) merge(g[i].x, g[i].y);
}
}
init(n), sort(g + 1, g + m + 1, Cmp);
for (read(q); q--; ) {
int s; read(s);
for (rg int x, i = 1; i <= s; ++i)
read(x), e[i] = (edge) { g[x].tx, g[x].ty, g[x].val };
sort(e + 1, e + s + 1, cmp);
int flag = 1;
for (rg int i = 1; i <= s && flag; ) {
int j = i;
do {
if (findd(e[j].x) == findd(e[j].y)) { flag = 0; break; }
merge(e[j].x, e[j].y), ++j;
} while (j <= s && e[j].val == e[i].val);
while (i < j) fa[e[i].x] = e[i].x, fa[e[i].y] = e[i].y, ++i;
}
puts(flag ? "YES" : "NO");
}
return 0;
}
完结撒花 (qwq)
以上是关于「CF891C」Envy的主要内容,如果未能解决你的问题,请参考以下文章