luogu1330_封锁阳光大学 图的遍历
2024-08-25 02:47:57
解释:(转自洛谷题解)
首先,肯定要明确一点,那就是这个图是不一定联通的。于是,我们就可以将整张图切分成许多分开的连同子图来处理。然而最重要的事情是:如何处理一个连通图?
乍看下去,似乎无从下手,因为方案好像有很多种,根本就枚举不完。但是,关键要注意到题目中重要的两个条件,我们把它抽象成这两个要素:
①每一条边所连接的点中,至少要有一个被选中。
②每一条边所连接的两个点,不能被同时选中。
由此,可以推断出:每一条边都有且仅有一个被它所连接的点被选中。
又因为我们要处理的是一个连通图。所以,对于这一个图的点的选法,可以考虑到相邻的点染成不同的颜色。
于是,对于一个连通图,要不就只有两种选法(因为可以全部选染成一种色的,也可以全部选染成另一种色的),要不就是impossible!
所以,我们只需要找到每一个子连通图,对它进行黑白染色,然后取两种染色中的最小值,然后最后汇总,就可以了。
另外,要判断impossible,只需要加一个used数组,记录已经遍历了哪些点。如果重复遍历一个点,且与上一次的颜色不同,则必然是impossible的。、
my code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (int i = a; i <= b; ++i) const int N = 1e5 + ; int n, m, vis[N], cnt[], ans; bool used[N]; vector<int> e[N]; void dfs(int u, int col) {
if (!used[u]) {
used[u] = ;
vis[u] = col;
cnt[col]++;
for (auto v : e[u]) {
dfs(v, - col);
}
}
else if (col != vis[u]) {
puts("Impossible");
exit();
}
} int main() {
scanf("%d%d", &n, &m); rep(i, , m) {
int u, v;
scanf("%d%d", &u, &v);
e[u].push_back(v);
e[v].push_back(u);
} rep(i, , n) if (!used[i]) {
cnt[] = cnt[] = ;
dfs(i, );
ans += min(cnt[], cnt[]);
} printf("%d\n", ans); return ;
}
最新文章
- 数据结构->;直接插入排序
- 安装 SSL 证书
- Linux内核分析——第七周学习笔记20135308
- Vue.js学习 Item11 – 组件与组件间的通信
- nohub命令
- 转: 透过CAT,来看分布式实时监控系统的设计与实现
- Orchard中的多语言功能
- OpenProcess() 函数
- leetcode先刷_Search in Rotated Sorted Array II
- 安装sysbench遇到找不到库文件的问题
- HashMap、HashTable与ConcurrentHashMap区别
- 涂抹mysql笔记-数据库中的权限体系
- 14. The Realities of Telecommuting 远程办公的现状
- linux内核分析第七次实验
- Kafka常用命令收录
- 2.3.2 EditText(输入框)详解
- 【docker】 追加端口映射时 报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
- TCP/IP理解
- final,finally和 finalize的区别
- mysql按年度、季度、月度、周、日统计查询的sql语句