UVALive

n个点的一张图,问能否给每个点染上三种颜色中的一种,使得没有相邻的点颜色相同?

n <= 35。

Sample Input
4
6
6
0 3
1 5
3 2
2 5
0 4
1 0
7
12
6 5
0 3
2 6
3 5
5 0
0 4
4 5
6 3
1 4
1 2
3 4
2 3
7
8
6 5
0 3
2 6
3 5
1 4
1 2
3 4
2 3
6
9
0 1
1 2
2 3
5 2
5 3
3 4
2 4
1 4
4 5

Sample Output
Y
N
Y
N

  

先想的求出最大团,然后如果最大团的点数 > 3一定不可以。

最大团的点数 <= 3呢?一定可以吗?不是这样的。

下面这个图最大团是3,然而也是不满足条件的。

可以搜索,枚举第一个点染的颜色,就可以3*2^(n-1)暴力。

然而有一个优化就是可以先求出所有的联通块,然后对每个联通块这样暴力。

场上写的T了。。被大佬们反杀。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;
const int maxn = 30;
const int maxm = 1000;
const int INF=0x7f7f7f7f;

int v[maxm], nxt[maxm], last[maxm];
int vis[maxn], d[maxn];
vector<int> vc[maxn];
int sz = 0;
int n, m;

void DFS(int k, int p)
{
    vc[p].push_back(k);
    vis[k] = 1;
    for (int i = last[k]; i; i = nxt[i])
        if (!vis[v[i]]) DFS(v[i], p);
}

void init()
{
    sz = 0;
    for (int i = 0; i < maxn; i++) vc[i].clear();
    memset(last, 0, sizeof(last));
    memset(vis, 0, sizeof(vis));
    memset(d, 0, sizeof(d));
}

void build(int x, int y)
{
    sz++;
    v[sz] = y, nxt[sz] = last[x], last[x] = sz;
}

bool ok(int k)
{
    for (int i = last[k]; i; i = nxt[i])
        if (d[k] == d[v[i]]) return false;
    return true;
}

bool check(int p, int k)
{
    if (k == vc[p].size()) return true;
    int x = vc[p][k];
    for (int i = 1; i <= 3; i++)
    {
        d[x] = i;
        if (!ok(x)) continue;
        if (check(p, k+1)) return true;
    }
    d[x] = 0;
    return false;
}

int main()
{
    int t;
    scanf("%d", &t);
    for (int ca = 1; ca <= t; ca++)
    {
        init();
        scanf("%d%d", &n, &m);

        for (int i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            build(x, y), build(y, x);
        }

        int cnt = 0;
        for (int i = 0; i < n; i++)
            if (!vis[i])
            {
                ++cnt;
                DFS(i, cnt);
            }


        int flag = true;
        for (int i = 1; i <= cnt; i++)
            if (!check(i, 0)) { flag = false; break; }

        printf("%c
", flag ? 'Y':'N');

    }
}
原文地址:https://www.cnblogs.com/ruthank/p/9539112.html