从CF1702E看二分图判断的两种方法

https://www.luogu.com.cn/problem/CF1702E

1|0转化题意

把所有数连边,判断是否为二分图。

2|0染色法

void solve() { #define tests int n; std::cin >> n; std::map<int, std::vector<int>> edge; std::vector<bool> used(n + 1); bool ok(true); for (int i = 0; i < n; i++) { int a, b; std::cin >> a >> b; edge[a].push_back(b); edge[b].push_back(a); if (a == b or sz(edge[a]) > 2 or sz(edge[b]) > 2) {ok = false;}//出现次数大于二 } if (not ok) {NO; return ;} auto dfs = [&](auto self, int now) -> int { used[now] = true; for (auto to : edge[now]) if (not used[to]) { return self(self, to) + 1; } return 1; };//其实也是判断有没有奇环,显然总数加起来如果是奇数就是奇环 for (int i = 0; i < n; i++) { if (not used[i + 1] and (dfs(dfs, i + 1) & 1)) { ok = false; } } ok ? YES : NO; }

3|0扩展域并查集

//扩展域并查集维护是否为二分图 //构造出x的敌人x+n和y的敌人y+n //因为是分成两个集合,所以只要构造一个敌人(即另一个与自己相等的数,但不能放到同一个集合内所以称为敌人) //把x和y的敌人合并,y和x的敌人合并 //如果x和自己的敌人在一个并查集,就不合法 void solve() { #define tests int n; std::cin >> n; std::vector<int> cnt(n); DSU dsu(n * 2); for (int i = 0; i < n; i++) { int x, y; std::cin >> x >> y; x--, y--; cnt[x]++; cnt[y]++; dsu.merge(x, y + n); dsu.merge(x + n, y); } bool ok(true); for (int i = 0; i < n; i++) { if (cnt[i] > 2) ok = false; if (dsu.find(i) == dsu.find(i + n)) ok = false; } ok ? YES : NO; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/18069306.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示