2021.02.25分教室
题目描述
n个人参加某项特殊考试。为了公平,要求任何两个认识的人不能分在同一个考场。求最少需要分几个考场才能满足条件。
输入格式
第一行,一个整数n(1<n<100),表示参加考试的人数。 第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识(编号从1开始)
输出格式
一行一个整数,表示最少分几个考场。
样例输入
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
样例输出
4
思路
由于数据量较小,可以直接搜索
代码
class Solution{
int[][] rela = new int[110][110];
int[][] room = new int[110][110];
int[] cnt = new int[110];
int ans = 999;
int n,m;
boolean[] isVis = new boolean[110];
void test() {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
m = cin.nextInt();
for(int i = 0; i < m; i++) {
int u = cin.nextInt();
int v = cin.nextInt();
rela[u][v] = 1;
rela[v][u] = 1;
}
dfs(1,0);
System.out.println(ans);
}
// p指同学的标号 r指分配了r个教室,对应下标r-1
void dfs(int p, int r) {
if(r >= ans) return; //剪枝
if(p == n+1) { //更新最少教室数
ans = Math.min(ans, r);
return;
}
//给第p个人分配教室
for(int i = 0; i < r; i++) {
boolean isIn = true;
int len = cnt[i];
//看教室中的第j个人是否认识第p个人
for(int j = 0;j < len; j++) {
if(rela[p][room[i][j]]==1) {
isIn = false; //进入下一教室
break;
}
}
//如果第i个教室可以将其容纳进去
if(isIn) {
room[i][len] = p;
cnt[i]++;
dfs(p+1,r);
//回溯状态
room[i][len] = 0;
cnt[i]--;
} else { //该教室不能容纳,看下一个教室
//无步骤自动进入下一教室
}
}
//若所有教室枚举完后,仍没有一条路径到达n+1,则需要重新开辟教室
room[r][0] = p;
cnt[r]++;
dfs(p+1,r+1);
room[r][0] = 0;
cnt[r]--;
}
}