[蓝桥杯]分考场
程序员文章站
2022-06-09 17:08:56
...
[蓝桥杯]分考场
分考场:
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遍历点,遍历考室,如果该考室有该点认识的人,则检查下一个考室,反之加入该考室,并回溯。如果所有考室都有人认识该考生,那么就新增一个考室,然后回溯。直到所有学生都检查完了,再比较结果。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 101;
int n, m;
int G[maxn][maxn];
int room[maxn][maxn];
int num = maxn;
void dfs(int x, int r){
if(r >= num) return ;
if(x == n+1){
num = min(num, r);
return ;
}
int k, i;
for(i = 1; i<=r; i++){
k = 0;
while(!G[room[i][k]][x] && room[i][k]) k++;
if(room[i][k] == 0){
room[i][k] = x;
dfs(x+1, r);
room[i][k] = 0;
}
}
room[i][0] = x;
dfs(x+1, r+1);
room[i][0] = 0;
}
int main(){
cin>>n>>m;
memset(G, 0, sizeof(G));
memset(room, 0, sizeof(room));
for(int i = 0; i<m; i++){
int a, b;
cin>>a>>b;
G[a][b] = G[b][a] = 1;
}
dfs(1, 1);
cout<<num<<endl;
return 0;
}
上一篇: asp程序执行数据库的效率提升建议
下一篇: 基于servlet实现统计网页访问次数