问题描述
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
输入格式
第一行,一个整数n(1<n<100),表示参加考试的人数。
第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
输出格式
一行一个整数,表示最少分几个考场。
样例输入
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
样例输出
4
Solution:
- 暴力枚举所有情况 即第x个人分配在这个考场 或者 重新开一个考场 。
- 用 vis 数组标记关系, g 数组维护第 i 个人分配在哪个考场 。
- 注意考场上 大于等于 ans 时候的剪枝 。
ps: 不知道为什么用ArrayList数组维护每个考场分配的人数为啥只有40分, 等这阵子学完Java再回头来填这个坑。
代码:
import java.math.BigInteger;
import java.util.*;
public class Main {
static Scanner cin = new Scanner(System.in);
static Main mains = new Main();
public static void main(String[] args) {
long start=System.currentTimeMillis();
doing();
long end=System.currentTimeMillis();
// System.out.println("程序运行时间:"+(end-start)+"ms");
}
static int N = 100 + 5;
static int n, m, ans;
static int g[] =new int[N];
static boolean vis[][] = new boolean[N][N];
public static void doing() {
n = cin.nextInt(); m = cin.nextInt();
for(int i = 1; i <= m; i++) {
int u = cin.nextInt(), v = cin.nextInt();
vis[u][v]=true; vis[v][u]=true;
}
ans = Integer.MAX_VALUE;
dfs(1, 0);
System.out.println(ans);
}
private static void dfs(int x, int s) {
if(s >= ans) return ;
if(x >= n+1) {
ans = s;
return ;
}
int i;
for(i = 1; i<= s; i++) {
boolean flag = true;
for(int y = 1; y <= n; y++) {
if(vis[x][y] && g[y]==i) {
flag = false;
break;
}
}
if(flag) {
g[x] = i;
dfs(x+1 , s);
g[x] = 0;
}
}
g[x] = s+1;
dfs(x+1, s+1);
g[x] = 0;
}
}