Crime

来源:互联网 发布:wto数据库 编辑:程序博客网 时间:2024/06/01 09:21

Crime

这里写图片描述

题意:给出n个点m条边,每条边有且只能选一个点,问最少选多少个点
.
.
题解:经典的黑白染色,dfs一次就可以了

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 101000;const int maxm = 100100;int a[2*maxm], nextt[2*maxm], last[maxn], n, m, tot, t, sum;int f[maxn];bool flag;int min(int x, int y) {    if (x<y) return x;    return y;}void insert(int x, int y) {    tot++;    a[tot] = y;    nextt[tot] = last[x];    last[x] = tot;}void dfs(int x) {    sum++;    if (f[x] == 1) t++;    int k = last[x];    while (k != 0) {        if (f[a[k]] == 0) {            f[a[k]] = -f[x];            dfs(a[k]);        } else if (f[a[k]] == f[x]) {            flag = false;            return;        }        if (!flag) return;        k = nextt[k];    }}int main() {    while (scanf("%d %d", &n, &m) != EOF) {        memset(last, 0, sizeof(last));        memset(a, 0, sizeof(a));        memset(nextt, 0, sizeof(nextt));        memset(f, 0, sizeof(f));        tot = 0;        flag = true;        int x, y, ans = 0;        for (int i = 1; i <= m; i++) {            cin >> x >> y;            insert(x, y);            insert(y, x);        }        for (int i = 1; i <= n; i++) if (f[i] == 0) {            sum = 0;            t = 0;            f[i] = 1;            dfs(i);            ans += min(sum-t, t);        }        if (!flag) {            cout << "Impossible" << endl;        } else         cout << ans << endl;    }}
0 0
原创粉丝点击