题意:
求一个图的最大点独立集.
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 ", ret); for (int i = 1, j = 0; i <= N; ++i) { if (opt[i]) { printf(j == 0 ? "%d" : " %d", i); ++j; } } puts(""); } return 0; }