【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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值