AT4162 [ARC099C] Independence

AT4162 [ARC099C] Independence

对于完全子图,考虑补图性质,即图内任意两个均无边。

若原图可分为两个完全子图,那么补图内子图无边,两子图间可有边,这不正是二分图吗?

染色判断奇环无解,求出每连通块答案,可行性 DP 计算答案即可。

时间复杂度 O ( n ) \mathcal O(n) O(n)

#include

using namespace std;

typedef long long ll;

#define int long long

#define ha putchar(' ')
#define he putchar('\n')

inline int read() {
	int x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')
			f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
		x = x * 10 + c - '0', c = getchar();
	return x * f;
}

inline void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

const int _ = 705;

int n, m, cnt, ans, t[3], c[_], t1[_], t2[_];

bool mp[_][_], f[_][_];

int tot, head[_], to[_ * _], nxt[_ * _];

void add(int u, int v) {
	to[++tot] = v, nxt[tot] = head[u], head[u] = tot;
	to[++tot] = u, nxt[tot] = head[v], head[v] = tot;
}

void dfs(int u) {
	t[c[u]]++;
	for (int i = head[u]; i; i = nxt[i]) {
		int v = to[i];
		if (c[v]) {
			if (c[u] == c[v]) {
				write(-1);
				exit(0);
			}
			continue;
		}
		c[v] = (c[u] == 1 ? 2 : 1);
		dfs(v);
	}
}

signed main() {
	n = read(), m = read(), ans = n * n;
	for (int i = 1, u, v; i <= m; ++i) {
		u = read(), v = read();
		mp[u][v] = mp[v][u] = 1;
	}
	for (int i = 1; i <= n; ++i)
		for (int j = i + 1; j <= n; ++j)
			if (!mp[i][j]) add(i, j);
	for (int i = 1; i <= n; ++i)
		if (!c[i]) {
			cnt++, c[i] = 1, t[1] = t[2] = 0;
			dfs(i);
			t1[cnt] = t[1], t2[cnt] = t[2];
		}
	f[0][0] = 1;
	for (int i = 1; i <= cnt; ++i)
		for (int j = 0; j <= n; ++j)
			if (f[i - 1][j])
				f[i][j + t1[i]] = f[i][j + t2[i]] = 1;
	for (int i = 0; i <= n; ++i)
		if (f[cnt][i]) ans = min(ans, i * (i - 1) / 2 + (n - i) * (n - i - 1) / 2);
	write(ans), he;
	return 0;
}

你可能感兴趣的:(二分图)