POJ_1419
好像有人2^N枚举才跑了125ms,所以如果加入简单的回溯的话,很容易跑得比较快。每次找到一个未染色的点的时候实际上有两种决策,要么保持这个点未染色的状态,要么就染成黑色并将其相邻的点染成白色。
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXD 110 #define MAXM 20010 #define INF 0x3f3f3f3f int N, M, first[MAXD], e, next[MAXM], v[MAXM], ANS; int col[MAXD], list[MAXD]; void add(int x, int y) { v[e] = y; next[e] = first[x], first[x] = e ++; } void init() { int i, x, y; scanf("%d%d", &N, &M); memset(first, -1, sizeof(first[0]) * (N + 1)), e = 0; for(i = 0; i < M; i ++) { scanf("%d%d", &x, &y); add(x, y), add(y, x); } } void dfs(int cur, int n) { for(; col[cur] != 0 && cur <= N; cur ++); if(cur == N + 1) { if(n > ANS) { ANS = n; int cnt = 0; for(int i = 1; i <= N; i ++) if(col[i] == -1) list[cnt ++] = i; } return ; } col[cur] = -1; for(int i = first[cur]; i != -1; i = next[i]) ++ col[v[i]]; dfs(cur + 1, n + 1); col[cur] = 0; for(int i = first[cur]; i != -1; i = next[i]) -- col[v[i]]; dfs(cur + 1, n); } void solve() { memset(col, 0, sizeof(col[0]) * (N + 1)); ANS = 0; dfs(1, 0); printf("%d\n", ANS); printf("%d", list[0]); for(int i = 1; i < ANS; i ++) printf(" %d", list[i]); printf("\n"); } int main() { int t; scanf("%d", &t); while(t --) { init(); solve(); } return 0; }