dfs;
按照 写的,大致思路是:
刚开始所有点没有着色,且最终结果至少有一个点被着黑色(一个点时直接着黑色,多个点时,可以任选一个点为黑色,其余点全为白色);
枚举这个黑色的点,并且把与它相邻的点都着白色,剩下的可以看作是一个相同的子问题了,因为剩下的点都不与这个黑色的点相邻。
最优解满足:每个白色的点至少与一个黑色的点相邻(如果这个点相邻的都是白色,可以把它改为黑色),且每个黑色的点周围都是白色。
# include# include # define N 105int n, m, ans;char g[N][N], c[N], f[N];void dfs(int cnt, int k){ int i, j, top, s[N]; if (cnt >= n && k > ans) { ans = k; memcpy(f, c, sizeof(f)); return ; } for (i = 1; i <= n; ++i) { if (!c[i]) { c[i] = 2; /* black */ top = 0; s[top++] = i; for (j = 1; j <= n; ++j) if (g[i][j] && !c[j]) { c[j] = 1; /* white */ s[top++] = j; } dfs(cnt+top, k+1); for (; top;) c[s[--top]] = 0; } } return ;}int main(){ char first; int T, i, u, v; scanf("%d", &T); while (T--) { memset(g, 0, sizeof(g)); scanf("%d%d", &n, &m); for (i = 0; i < m; ++i) { scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 1; } ans = 0; memset(c, 0, sizeof(c)); memset(f, 0, sizeof(f)); dfs(0, 0); printf("%d\n", ans); first = 1; for (i = 1; i <= n; ++i) if (f[i] == 2) { if (first) first = 0; else putchar(' '); printf("%d", i); } putchar('\n'); } return 0;}
//