P1418 选点问题
- 74通过
- 240提交
- 题目提供者tinylic
- 标签云端
- 难度普及+/提高
- 时空限制1s / 128MB
提交 讨论 题解
最新讨论更多讨论
- 非常重要!!
- 90分的点这里
题目描述
给出n个点,m条边,每个点能控制与其相连的所有的边,要求选出一些点,使得这些点能控制所有的边,并且点数最少。同时,任意一条边不能被两个点控制
输入输出格式
输入格式:
第一行给出两个正整数n,m
第2~m+1行,描述m条无向边
每行给出x,y,表示一条无向边(x,y)
输出格式:
输出最少需要选择的点的个数,如果无解输出“Impossible”(不带引号)
输入输出样例
输入样例#1:
7 5
1 2
1 3
5 6
6 7
1 2
输出样例#1:
2
说明
【数据范围】
对于30%的数据1<=n<=100
对于100%的数据1<=n<=1000
m<=n^2
不保证图连通
【题目来源】
tinylic改编
分析:其实也没啥好分析的......对于每一个点,我们给他染色,这个点所连到的点必须不能被染色,要是已经被染色了,则输出Impossible,很好理解。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n, m,head[100010],nextt[2000020],to[2000020],tot,vis[100010],col[100010],sum[3],ans; void add(int x, int y) { to[tot] = y; nextt[tot] = head[x]; head[x] = tot++; } bool dfs(int u, int c) { //printf("%d ", u); sum[c]++; col[u] = c; vis[u] = 1; for (int i = head[u]; i != -1; i = nextt[i]) { int v = to[i]; if (vis[v] && col[v] == col[u]) return false; else if (!vis[v] && !dfs(v, 3 - c)) return false; } return true; } int main() { memset(head, -1, sizeof(head)); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int a, b; scanf("%d%d", &a, &b); add(a, b); add(b, a); } for (int i = 1; i <= n; i++) if (!vis[i]) { sum[1] = sum[2] = 0; if (!dfs(i, 1)) { printf("Impossible"); return 0; } ans += min(sum[1], sum[2]); } printf("%d ", ans); return 0; }