题意:
求一个图的最大点独立集.
SOL:
转化为补图的最大团,最大团似乎是一个NP问题,那么只好爆搜了.
补一补图论基础,代码不想打了,来自某blog
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std; int N, M, mp[105][105];
int ret, cnt, opt[105], st[105]; void dfs(int x) {
if (x > N) { // 如果枚举了所有的节点
ret = cnt;
memcpy(opt, st, sizeof (st)); // 用一个更大的极大团替代原有的极大团
return;
}
int flag = true;
for (int i = 1; i < x; ++i) { // 检测新加入的点是否到团中的其他节点都存在一条边
if (st[i] && !mp[i][x]) {
flag = false;
break;
}
}
if (flag) { // 如果该节点满足在这个团中
st[x] = 1, ++cnt; // 该节点被加入到完全子图中去
dfs(x + 1);
st[x] = 0, --cnt;
}
if (cnt+N-x > ret) { // 跳过x节点进行搜索同时进行一个可行性判定
dfs(x + 1);
}
} int main() {
int T, x, y;
scanf("%d", &T);
while (T--) {
ret = cnt = 0;
scanf("%d %d", &N, &M);
memset(st, 0, sizeof (st));
for (int i = 0; i < 105; ++i) {
fill(mp[i], mp[i]+105, 1);
}
while (M--) {
scanf("%d %d", &x, &y);
mp[x][y] = mp[y][x] = 0;
}
dfs(1);
printf("%d\n", ret);
for (int i = 1, j = 0; i <= N; ++i) {
if (opt[i]) {
printf(j == 0 ? "%d" : " %d", i);
++j;
}
}
puts("");
}
return 0;
}