【dfs】【暴力】分考場

問題描述
  n個人參加某項特殊考試。
  爲了公平,要求任何兩個認識的人不能分在同一個考場。
  求是少需要分幾個考場才能滿足條件。
輸入格式
  第一行,一個整數n(1<n<100),表示參加考試的人數。
  第二行,一個整數m,表示接下來有m行數據
  以下m行每行的格式爲:兩個整數a,b,用空格分開 (1<=a,b<=n) 表示第a個人與第b個人認識。
輸出格式
  一行一個整數,表示最少分幾個考場。


 最近的思維定勢特別多,需要改正。第一眼看這題,woc這肯定是最大團了。畢竟一個子完全圖的各個端點肯定屬於不同的考場。迅速地寫了一發交上去WA。後來想了一段時間才意識到根本和最大團沒啥關係,答案的數目完全可以比最大團的大小要大。一個例子就是五個端點的環,最大團是2,然而必須要三個教室,類似的圖還有:
在這裏插入圖片描述
 這個圖最大團是3,但是拿三色去染會發生矛盾,至少需要四色。
 實際上這題的解法,還是需要暴搜,從左到右枚舉每個編號的同學,枚舉他能呆在哪個已有的教室,或是呆在一個新教室。乍一看100好像很大,實際上寫得正常的話都可以過,數據不那麼噁心。

#include<cstdio>
#include<vector>
#include<algorithm>
#include<bitset>
using namespace std;

int n,m,cnt,ans=1E9,h[105];
vector<int> E[105];
bitset<105> B[105];

bool get(int x)  //提取可能選擇
{
	for(int j=0;j<E[x].size();j++)
		if(h[E[x][j]])
			B[x][h[E[x][j]]]=true;		
}

void dfs(int x)
{
	if(cnt>=ans)
		return ;
	if(x>n)
	{
		ans=cnt;
		return ;
	}
	B[x].reset();
	get(x);
	for(int i=1;i<=cnt;i++)
		if(!B[x][i])
		{
			h[x]=i;
			dfs(x+1);
			h[x]=0;
		}
	cnt++;
	h[x]=cnt;
	dfs(x+1);  //新教室
	h[x]=0;
	cnt--;
} 

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		if(u>v)
			swap(u,v);
		E[v].push_back(u);
	}
	for(int i=1;i<=n;i++)
		sort(E[i].begin(),E[i].end()),unique(E[i].begin(),E[i].end());
	dfs(1);
	printf("%d",ans);
	return 0;
}