欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[蓝桥杯]分考场

程序员文章站 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;
}
相关标签: 刷题之旅