问题描述
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
输入格式
第一行,一个整数n(1<n<100),表示参加考试的人数。
第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
第二行,一个整数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
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
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
样例输出
5
正解
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 1e2+5;
typedef long long ll;
int Vec[N][N]; //存放朋友,值为一是朋友
int Set[N][N]; //存放教室里的人
int SetCnt[N]; //教室里的人数
int n,m,a,b;
int res = 100;
void solve(int k,int q){ //开始处理第k个人,已经用了q个教室
if(q>=res){ //当现在安排的数量已经大于了最小的教室数量的话,返回
return;
}
if(k>n){ //安排的学生已经大于所有的学生了,就是安排完所有的学生了已经
res=min(res,q);
return;
}
for(int i=1;i<=q;i++){ //首先看看之前的房间i里面能不能放进去
int KnowFlag = 0;
int sz=SetCnt[i];//看看他熟悉的人在不在i房间
for(int j=1;j<=sz;j++){
if(Vec[k][Set[i][j]]==1){
KnowFlag = 1;
break; //有认识的人
}
}
if(KnowFlag==0){//这个房间可以放人
Set[i][ ++SetCnt[i] ] = k; //将这个学生存到这个考场中
solve(k+1,q);
SetCnt[i]--;
}
}
//重新开一个房间
Set[q+1][ ++SetCnt[q+1] ] = k; //将这个学生存到这个考场中
solve(k+1,q+1);
SetCnt[q+1]--;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// 用set存储每个教室的人 用vector存储每个人的熟悉的人
cin>>n>>m;
// n个人m个关系
for(int i = 0;i<m; i++) {
cin>>a>>b;
Vec[a][b] = Vec[b][a] = 1;
}
solve(1,1);
cout<<res<<endl;
return 0;
}
用stl的vector和set超时了,比赛的时候看不到结果,还是能手写尽量手写吧(80分代码)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 1e2+5;
typedef long long ll;
vector<int> Vec[N];
set<int> Set[N];
int n,m,a,b;
int res = 100;
void solve(int k,int q){ //开始处理第k个人,已经用了q个教室
if(q>=res){ //当现在安排的数量已经大于了最小的教室数量的话,返回
return;
}
if(k>n){ //安排的学生已经大于所有的学生了,就是安排完所有的学生了已经
res=min(res,q);
return;
}
int sz=Vec[k].size();//看看他熟悉的人在不在i房间
for(int i=1;i<=q;i++){ //首先看看之前的房间i里面能不能放进去
int KnowFlag = 0;
for(int j=0;j<sz;j++){
if(Set[i].count( Vec[k][j] )){
KnowFlag = 1;
break; //有认识的人
}
}
if(KnowFlag==0){//这个房间可以放人
Set[i].insert(k); //将这个学生存到这个考场中
solve(k+1,q);
Set[i].erase(k);
}
}
//重新开一个房间
Set[q+1].insert(k); //将这个学生存到这个考场中
solve(k+1,q+1);
Set[q+1].erase(k);
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// 用set存储每个教室的人 用vector存储每个人的熟悉的人
cin>>n>>m;
// n个人m个关系
for(int i = 0;i<m; i++) {
cin>>a>>b;
Vec[a].push_back(b);
Vec[b].push_back(a);
}
solve(1,1);
cout<<res<<endl;
return 0;
}