UVA 193 - Graph Coloring

这道题也是一道染色的题,只有黑、白两种颜色,要求有边的两个点不能染成相同的颜色,我用回溯

法做的,判断与cur有边的点是否被染色,如果这些点中有一个点已经被染色,那么cur这点只能染与

被染色的点不同的颜色,我们就可以向下一个点搜索。如果cur周围的点没有被染色的话,那么cur这

点可以自由地染色,我们可以染成黑色或者白色,分两种情况向下一层搜索,直到将所有的点都染上

色。然后计数,看哪种情况染的黑色最多,将其复制到color数组中。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXN 110
int n, k, m, ans;
bool g[MAXN][MAXN], vis[MAXN];
int rec[MAXN], color[MAXN];

void init()
{
memset( vis, false, sizeof vis);
memset( g, false, sizeof g);
memset( rec, 0, sizeof rec);
memset( color, 0, sizeof color);
ans = 0;
}

void input()
{
int a, b;
for( int i = 0; i < k; i ++)
{
scanf( "%d%d",&a, &b);
g[a][b] = g[b][a] = true;
}
}

void dfs( int cur)
{
if( cur > n) //因为是从1开始搜,所以cur等于n+1时就认为得到了一次结果
{
int t = 0;
for( int i = 1; i <= n; i ++)
if( rec[i] == 1) t ++;
if( t > ans) //判断是否比当前的结果多
{
ans = t;
memcpy( color, rec, sizeof rec); //将最新的染色情况复制到color数组中
}
}
else{
bool flag = false;
for( int i = 1; i <= n; i ++)
if( g[cur][i] && vis[i])
{
flag = true;
break;
}
if( flag) dfs( cur + 1);
else {
vis[cur] = true; // 设置使用标志
rec[cur] = 1;
dfs( cur + 1);
vis[cur] = false; //清除标志
rec[cur] = 0;
dfs( cur + 1);
}
}
}


int main()
{
scanf( "%d", &m);
while( m --)
{
scanf( "%d%d", &n, &k);
init();
input();
dfs( 1);
printf( "%d\n", ans);
int tt = 0;
for( int i = 1; i <= n; i ++)
{
if( color[i] == 1) {
if( ++ tt < ans)
printf( "%d ", i);
else
printf( "%d\n", i);
}
}
}
return 0;
}

 

你可能感兴趣的:(color)