题目描述
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
输入:
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
则程序应该输出:
5
资源约定:
峰值内存消耗 < 256M CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。 注意:
所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
思路
深搜回溯
代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int map[105][105]={0};
vector<int> room[10005];
int n,m,a,b;
int minRoomNum=1e8; //记录结果
void dfs(int id,int roomNum)
{
if(roomNum>=minRoomNum){ //如果当前房间数量已经大于最小房间数,不必要再继续搜索下去
return;
}
if(id==n+1){//如果已经搜索到最后一个人,那么没必要继续搜索
minRoomNum=min(minRoomNum,roomNum);
return;
}
for(int i=1;i<=roomNum;i++){
int flag=0;
for(int j=0;j<room[i].size();j++){ //搜索当前房间是否有人认识第id个人
if(map[id][room[i][j]]==1){ //认识则直接跳出当前循环
flag=1;
break;
}
}
if(flag==0){ //如果当前房间没有人认识第id个人,则将id放入当前房间,进行搜索
room[i].push_back(id);
dfs(id+1,roomNum);
room[i].erase(room[i].end()-1); //回溯
}
}
room[roomNum+1].push_back(id); //如果当前这个人在所有的房间中都有认识的人,则只能给他新开一个房间
dfs(id+1,roomNum+1);
room[roomNum+1].erase(room[roomNum+1].end()-1); //回溯
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
while(m--){
cin>>a>>b;
map[a][b]=map[b][a]=1;
}
dfs(1,0);
cout<<minRoomNum<<endl;
return 0;
}
有问题可以留言沟通哦