您的位置:首页 > 其它

洛谷P1418 选点问题

2017-06-28 22:28 211 查看
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\n", 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\n", ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: