一、题目
题目 1874: 蓝桥杯2017年第八届真题-分考场
时间限制: 1Sec 内存限制: 128MB 提交: 1262 解决: 320
题目描述
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
二、思路和代码
思路:一个个分配考试人员,若考场不够,则增加考场,深度有限,可以用dfs。
代码:一直只有80分,但看了看思路和大佬满分的代码差别不大(末尾链接),不知道问题出在哪。
n = int(input())
m = int(input())
ls = list()
# 构建矩阵存储,链式存储的好处在于能够一次遍历完,矩阵存储的好处是可以直接访问
nex = [[0 for _ in range(n+1)] for _ in range(n+1)]
for _ in range(m):
x, y = input().split()
x = int(x)
y = int(y)
nex[x][y] = 1
nex[y][x] = 1
# 最优房间数
leastrooms = n
# i, j存放i房间的第j人编号
roomsets = [[0 for _ in range(n+1)] for _ in range(n)]
# 房间里 人的总数
personnum = [0 for _ in range(n)]
# 思路:无向图染色问题,相邻结点不能染相同颜色。
# 考虑用dfs还是bfs首先考虑划分结点的依据,这题是将人放入不同的房间,这就需要确定房间数。
# 用dfs,将人一个个放入房间,此时只要有解就行,而不需要最优解。总体的框架其实是一个每层单结点的bfs
# 第一个深度是一个房间,第二个是两个房间,而实际上要判断每层是否到达结果还是用的dfs。
# 所以这题还是用的dfs
# 思路:若考场不够,则一个个增加考场,深度有限,可以dfs
# 总结:不一定要用set来加快,增加很删除不如一开始就分配好所有空间。
# dfs返回针对当前对第1..cur-1个人的安排至少需要多少个房间
def dfs(cur, rooms):
global roomsets, n, leastrooms
if cur > n:
leastrooms = min(leastrooms, rooms)
return
elif rooms >= leastrooms:
return
else:
# 将cur逐个放入房间i中,并记录最优房间数量
for i in range(rooms):
# 可以放入
num = personnum[i]
k = 0
for j in range(1, num+1):
if not nex[cur][roomsets[i][j]]:
k += 1
if k == num:
# 加入
personnum[i] += 1
roomsets[i][personnum[i]] = cur
dfs(cur+1, rooms)
# 恢复
personnum[i] -= 1
# 放入空房间
i += 1
personnum[i] += 1
roomsets[i][personnum[i]] = cur
dfs(cur+1, rooms+1)
# 恢复
personnum[i] -= 1
return
dfs(1, 1)
print(int(leastrooms))