历届试题 分考场
时间限制:1.0s 内存限制:256.0MB

问题描述
  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
样例输入
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>

using namespace std;

const int maxn = 101;

int n, m;

int rela[maxn][maxn];

int a, b;

int ans = 0;

int ceng[maxn];

void init(int s, bool cc[])
{
	for (int i = 1; i < s; i++)
	{
		if (rela[s][i])cc[ceng[i]] = 1;
	}
}

void dfs(int s, int layer)
{
	if (s > n)return;
	if (layer >= ans)return;
	
	//使用cc数字只遍历一遍,就找到所有的当前s学生不能进的考场,以空间换时间
	bool cc[maxn];
	memset(cc, 0, sizeof(cc));
	init(s, cc);

	//可知第s个学生放在第s+1个考场是没有任何意义的,所以i<=s
	//又可知,当我们现在遍历的考场不小于最佳答案,那么继续访问下去是没有任何意义的,所以i<ans
	//可知这样遍历,可以最快的遍历完所有有可能的最佳答案,然而还是超时了。。。。。。
	//其他博客写的都一样,是不是都是抄的啊,(哼~)
	for (int i = 1; i <= s && i < ans; i++)
	{
		if (cc[i])continue;
		ceng[s] = i;
		if (s + 1 > n)
		{
			ans = max(i, layer);
		}
		dfs(s + 1, max(layer, i));
	}
}

int main()
{
	cin >> n >> m;
	memset(rela, 0, sizeof(rela));
	for (int i = 0; i != m; i++)
	{
		cin >> a >> b;
		rela[a][b] = rela[b][a] = 1;
	}
	ans = n;
	//第一个学生一定放到第一个考场,放到第二个去和放到第一个是等价的,所以就只放在第一个考场了
	ceng[1] = 1;
	//之后从第二个考生,只有1个考场考试考察。
	dfs(2, 1);
	cout << ans << endl;
	return 0;
}