问题描述
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
样例输出
样例输入
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
样例输出
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <map> #include <set> #include <algorithm> #define PI 3.1415926535898 #define e 2.718281828459 using namespace std ; const int MAX = 1005 ; typedef long long LL ; int n ,m ; int ans ; int g[MAX][MAX] ; // 表示是否存在关系 int vis[MAX][MAX] ; // //vis[1][1] = 2 表示考场1里面第一个人是2号学生 // vis[1][2] = 3 表示考场1里面第二个认识3号学生 int cnt[MAX] ; // 表示考场中的学生人数 ,cnt[1] = 2 表示考场1 有2名 void add(int u ,int v){ g[u][v] = 1 ; g[v][u] = 1 ; } void dfs(int id , int num ){ if(num >= ans ){ // 剪枝 return ; } if(id == n+1){ ans = min(ans,num) ; return ; } for(int i = 1 ; i<=num ; i++) {// 看看前num 考场能不能放进去 int k = 0 ; bool flag = false ; k = cnt[i] ; // 取出第i考场的学生人数 ,然后进行枚举 for(int j = 1 ; j<=k ;j++){ // 枚举第 i 个考场的学生 if(g[id][vis[i][j]] == 1 ){ // 只要这个考场中有一个认识的也不行 flag = true ; break; } } if(!flag){ // 如果都不认识 vis[i][++cnt[i]] = id ; // 将这个学生加到这个教室中 dfs(id+1,num) ; // 安排下一个学生 cnt[i]--; //回溯 } } vis[num+1][++cnt[num+1]] =id ; // 没有的满足要求的教室,就重新开一个 dfs(id+1,num+1) ; --cnt[num+1] ; } int main(){ cin >> n >> m ; for(int i = 0 ;i<m ; i++ ){ int a ,b ; cin >> a >>b ; add(a,b) ; } ans = n ; dfs(1,0) ; cout<<ans; return 0 ; }
原文链接:https://blog.csdn.net/qq_41661809/article/details/88764266?ops_request_misc=&request_id=26e6c5c5af3b47eb8cf99e7fdd16ea02&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~koosearch~default-15-88764266-null-null.268%5Ev1%5Econtrol&utm_term=%E6%91%A9%E6%89%98%E8%BD%A6%E8%80%83%E5%9C%BA