对于每个学生,找到能够放下该学生的教室,如果找不到就新开一个教室,直到把该学生安顿下来,当然这个学生并不是非得放到当前教室,也可以放到后面的教室,这时就需要回溯。
import java.util.*;
import java.io.*;
public class Main {
static boolean[][] map = new boolean[110][110];
static LinkedList<Integer>[] list = new LinkedList[110];
static int ans = 0x3f3f3f3f;
static int n, m;
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
m = scan.nextInt();
while (m-- > 0) {
int a = scan.nextInt();
int b = scan.nextInt();
// 不和
map[a][b] = map[b][a] = true;
}
for (int i = 1; i <= n; i++) list[i] = new LinkedList<>();
dfs(1, 0); // 考虑第一个学生,目前没有一间教室
System.out.println(ans);
}
// stu: 第几个学生,cla:已用教室数
static void dfs(int stu, int cla) {
if (cla >= ans) return;
if (stu > n) {
// 找完了所有学生
ans = cla;
return;
}
for (int i = 1; i <= cla; i++) { // 遍历所有教室
// 遍历当前教室中的学生
int j = 0;
for (j = 0; j < list[i].size(); j++) {
// 判断是否与当前考虑学生stu冲突
if (map[stu][list[i].get(j)]) break;
}
if (j == list[i].size()) {
// 如果当前教室中没有人与它冲突,那么当前教室就可以放下该学生
list[i].add(stu);
dfs(stu + 1, cla);
// 回溯,也可以不放
list[i].removeLast();
}
}
// 到这里说明现有所有教室都与当前学生stu冲突,需要新开一个教室
list[cla + 1].add(stu);
dfs(stu + 1, cla + 1);
// 也可以不放在当前教室,回溯
list[cla + 1].removeLast();
}
}