题意:给出一张图,每个节点可以涂成黑色或者白色,如果节点是黑色的,那么和节点相连的点的颜色不能为黑色,输出涂完色的图上黑色点做多有几个,涂成黑色的点的编号都是多少。
题解:假设一开始图上的颜色都是白色,然后从第一个点开始递归,先判断当前点能否涂成黑色,如果可以,就涂成黑色,然后从下一个点开始继续判断,递归结束后将点重新变为白色(回溯),然后再次递归,此时不必涂黑,因为可以涂黑的点也可以选择不涂黑。
#include <stdio.h>
#include <string.h>
const int N = 100 + 5;
const int INF = 0x3f3f3f3f;
int n, k, g[N][N], vis[N], res[N], ans;
void init() {
memset(g, 0, sizeof(g));
memset(vis, 0, sizeof(vis));
memset(res, 0, sizeof(res));
ans = 0;
}
bool judge(int cur) {
for (int i = 1; i <= n; i++)
if (g[cur][i] && vis[i] == 1)
return false;
return true;
}
void dfs(int cur, int count) {
if (cur == n + 1) {
if (count > ans) {
ans = count;
int a = 0;
for (int i = 1; i <= n; i++)
if (vis[i] == 1)
res[a++] = i;
}
return;
}
if (judge(cur)) {
vis[cur] = 1;//涂黑
dfs(cur + 1, count + 1);//黑色点个数加一
vis[cur] = 0;//涂白
}
dfs(cur + 1, count);//涂白
}
int main() {
int t, a, b;
scanf("%d", &t);
while (t--) {
init();
scanf("%d%d", &n, &k);
for (int i = 0; i < k; i++) {
scanf("%d%d", &a, &b);
g[a][b] = g[b][a] = 1;
}
dfs(1, 0);
printf("%d\n", ans);
printf("%d", res[0]);
for (int i = 1; i < ans; i++)
printf(" %d", res[i]);
printf("\n");
}
return 0;
}