题意:平面内最多26个点,给出一些点与点之间的矛盾关系,问最少使用多少颜色才能给这些点染色,并保证矛盾点之间不同色。
分析:深搜,对于每个点先尝试已经给别的点染过的颜色,如果不行再尝试染新的颜色,注意新的颜色只需要尝试一次即可,因为各种新的颜色对于当前状态来说是等价的。
View Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define maxn 30 #define maxm maxn * maxn #define maxl maxn + 2 #define inf 0x3f3f3f3f struct Edge { int v, next; }edge[maxm]; int head[maxn]; int color[maxn]; int n; int edge_cnt; int ans; void addedge(int a, int b) { edge[edge_cnt].v = b; edge[edge_cnt].next = head[a]; head[a] = edge_cnt++; } void input() { edge_cnt = 0; memset(head, -1, sizeof(head)); char st[maxl]; for (int i = 0; i < n; i++) { scanf("%s", st); int len = strlen(st); for (int j = 2; j < len; j++) { addedge(i, st[j] - 'A'); addedge(st[j] - 'A', i); } } } bool ok(int a) { for (int i = head[a]; ~i; i = edge[i].next) if (color[a] == color[edge[i].v]) return false; return true; } void dfs(int color_num, int a) { if (a == n) { ans = min(ans, color_num); return; } for (int i = 0; i < color_num; i++) { color[a] = i; if (ok(a)) dfs(color_num, a + 1); } color[a] = color_num; dfs(color_num + 1, a + 1); color[a] = -1; } int main() { //freopen("t.txt", "r", stdin); while (scanf("%d", &n), n) { input(); ans = inf; memset(color, -1, sizeof(color)); dfs(0, 0); if (ans == 1) printf("1 channel needed.\n"); else printf("%d channels needed.\n", ans); } return 0; }