UVa 193 Graph Coloring

dfs;

按照 Staginner 大牛的方法写的,大致思路是:

刚开始所有点没有着色,且最终结果至少有一个点被着黑色(一个点时直接着黑色,多个点时,可以任选一个点为黑色,其余点全为白色);

枚举这个黑色的点,并且把与它相邻的点都着白色,剩下的可以看作是一个相同的子问题了,因为剩下的点都不与这个黑色的点相邻。

最优解满足:每个白色的点至少与一个黑色的点相邻(如果这个点相邻的都是白色,可以把它改为黑色),且每个黑色的点周围都是白色。

# include <stdio.h>
# include <string.h>

# define N 105

int 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;
}

//

原文地址:https://www.cnblogs.com/JMDWQ/p/2580349.html