问题大致如下:有n个学生参加考试,每个考场里的任意俩学生都不能认识,求需要的最少的考场的数量
首先输入学生数量n,输入m;接下来m行,每行两个数据i,j,表示i与j认识
样例输入:
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
其结果为4
首先如果是假如任何认识的学生在同一考场的话用并查集可以解决,但是这种问题怎么解决刚开始有点懵逼,后来一想直接暴力解决不就行了吗,遍历每一个房间,看看是否有房间可以放下这个学生,如果不行就在开一个新的房间
代码如下:
#include<iostream>
#include<stdio.h>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 100+1
bool Know[maxn][maxn] = {}; //标记认识的两个人
bool Room[maxn][maxn] = {}; // Room[i][j] = 1 表示第i个房间住第j号学生
void dfs(int &roomNumber , int stuId , int stuNumber) {
if (stuId == stuNumber + 1) //每次dfs都是找第stuId学生的房间号,这是递归出口
return;
for (int room = 1;room <= roomNumber;room++) {
bool ok = true; //ok表示这个房间是否可以放下第stuId个学生
for (int stu = 1;stu <= stuNumber;stu++) {
if (Room[room][stu] && Know[stu][stuId]) {
ok = false; // 这个房间放不下这个学生
break;
}
}
if (ok) {
Room[room][stuId] = true;
break;
}
else if (room == roomNumber) { //所有的已知房间都放不下,申请一个新的房间
roomNumber++;
Room[roomNumber][stuId] = true;
break;
}
}
dfs(roomNumber, stuId + 1, stuNumber);
}
int main()
{
int n,m;
cin >> n>>m;
for (int i = 1;i <= m;i++) {
int a, b;
cin >> a >> b;
Know[a][b] = Know[b][a] = true;
}
int roomNumber = 1;
int stuId = 1;
int stuNumber = n;
dfs(roomNumber , stuId, stuNumber);
cout << roomNumber << endl;
/*for (int i = 1;i <= roomNumber;i++) {
cout << i << " : ";
for (int j = 1;j <= stuNumber;j++) {
if (Room[i][j] == 1) {
cout << " " << j;
}
}
cout << endl;
}*/
}