传送门

解释:(转自洛谷题解)

首先,肯定要明确一点,那就是这个图是不一定联通的。于是,我们就可以将整张图切分成许多分开的连同子图来处理。然而最重要的事情是:如何处理一个连通图?

乍看下去,似乎无从下手,因为方案好像有很多种,根本就枚举不完。但是,关键要注意到题目中重要的两个条件,我们把它抽象成这两个要素:

①每一条边所连接的点中,至少要有一个被选中。

②每一条边所连接的两个点,不能被同时选中。

由此,可以推断出:每一条边都有且仅有一个被它所连接的点被选中。

又因为我们要处理的是一个连通图。所以,对于这一个图的点的选法,可以考虑到相邻的点染成不同的颜色。

于是,对于一个连通图,要不就只有两种选法(因为可以全部选染成一种色的,也可以全部选染成另一种色的),要不就是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 ;
}

最新文章

  1. 数据结构-&gt;直接插入排序
  2. 安装 SSL 证书
  3. Linux内核分析——第七周学习笔记20135308
  4. Vue.js学习 Item11 – 组件与组件间的通信
  5. nohub命令
  6. 转: 透过CAT,来看分布式实时监控系统的设计与实现
  7. Orchard中的多语言功能
  8. OpenProcess() 函数
  9. leetcode先刷_Search in Rotated Sorted Array II
  10. 安装sysbench遇到找不到库文件的问题
  11. HashMap、HashTable与ConcurrentHashMap区别
  12. 涂抹mysql笔记-数据库中的权限体系
  13. 14. The Realities of Telecommuting 远程办公的现状
  14. linux内核分析第七次实验
  15. Kafka常用命令收录
  16. 2.3.2 EditText(输入框)详解
  17. 【docker】 追加端口映射时 报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
  18. TCP/IP理解
  19. final,finally和 finalize的区别
  20. mysql按年度、季度、月度、周、日统计查询的sql语句

热门文章

  1. python工具函数
  2. 记一次SQL优化。
  3. POJ 2796:Feel Good(单调栈)
  4. 基于modelform和ajax的注册
  5. 利用Jmeter模拟Github登录
  6. 统计greenplum_postgresql数据占用存储情况
  7. 百度小程序自定义通用toast组件
  8. C语言中的函数与数学上的函数很类似
  9. NET Core CSharp初级篇 1-3面向对象
  10. 74859a颜色信息