题目链接:
P1330 封锁阳光大学 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解题思路:
由题意每条边只能存在一个点,要覆盖所有的边,求最少的点。翻译过来就是,每条边要被染成两种不同的颜色,选择被染颜色的最小值。
因为他不一定是一个连通图,所以他可能存在多个连通块,所以我们需要把每个连通块取得颜色最少的点的数目
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N = 10010, M = 200010; int n, m; int sum[3]; int color[N]; int h[N], e[M], ne[M], idx; void add(int a, int b) { e[idx] = b; ne[idx] = h[a]; h[a] = idx; idx ++ ; } bool dfs(int u, int c) { color[u] = c;//将u染成颜色c sum[c] ++ ;//c颜色出现的次数加1 for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (!color[j])//若未被染色 { if (!dfs(j, 3 - c)) return false;//将染成与u不同的另一种颜色 } else if (color[j] == c) return false;//否则判断j这个点和它的相邻点u的颜色是否存在矛盾 } return true; } int main() { cin >> n >> m; memset(h, -1, sizeof h); for (int i = 0; i < m; i ++ ) { int a, b; scanf("%d %d", &a, &b); add(a, b); add(b, a); } int ans = 0; for (int i = 1; i <= n; i ++ ) { if (!color[i]) //若未被染色 { memset(sum, 0, sizeof sum);//记录每个连通块中颜色最少的点 if (!dfs(i, 1))//将它染成1这种颜色 { puts("Impossible"); return 0; } ans += min(sum[1], sum[2]);//加上每个连通块中颜色最少的点 } } cout << ans << endl; return 0; }
07-12
663
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交