1. 程式人生 > 實用技巧 >【圖著色】暴力dfs

【圖著色】暴力dfs

題目連結

題意

n個人參加某項特殊考試。

為了公平,要求任何兩個認識的人不能分在同一個考場。

求是少需要分幾個考場才能滿足條件。

思路

暴力 dfs 求解

程式碼

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 3e2 + 10;

int n, m, rel = inf;
int arr[N][N], cpy[N];
vector<int> vec[N];
void dfs(int id, int sum)//為第 id 個人分配考場,已經使用了sum個考場
{
    if (id > n) {
        rel = min(rel, sum);
        return;
    }
    if (sum >= rel)//剪枝
        return;
    for (int i = 1; i <= sum; i++) {//使用現有的sum個考場
        int flag = 1;
        for (int j = 0; j < vec[i].size(); j++) {
            if (arr[id][vec[i][j]]) {
                flag = 0;
                break;
            }
        }
        if (flag) {
            vec[i].pb(id);
            dfs(id + 1, sum);
            vec[i].pop_back();
        }
    }
    vec[sum + 1].pb(id);
    dfs(id + 1, sum + 1);//新開一個考場
    vec[sum + 1].pop_back();
}
int main()
{
    while (~scanf("%d%d", &n, &m)) {
        rel = inf;
        for (int i = 1; i <= n; i++) {
            vec[i].clear();
        }
        memset(arr, 0, sizeof(arr));
        for (int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            arr[u][v] = arr[v][u] = 1;
        }
        dfs(1, 1);
        printf("%d\n", rel);
    }
    return 0;
}