这题一开始看着数据很小用的纯暴力,还是超时了,
#include<bits/stdc++.h>
using namespace std;
int a[105][105],p[105],n,m,minn=1000;
int check(int k,int color)
{
int i;
for(i=1;i<=n;i++)
if(a[k][i])
if(p[i]==color)
return 0;
return 1;
}
int flag=0;
int search1(int point)
{
int i;int maxn=0;
if(point>n)
{
for(i=1;i<=n;i++)
{
if(maxn<p[i])
maxn=p[i];
}
if(maxn<minn)
minn=maxn;
flag=1;
return 0;
}
for(i=1;i<=n;i++)
{
p[point]=i;
if(i>=minn)
break;
if(check(point,i))
search1(point+1);
}
return 0;
}
int main(){
scanf("%d %d",&n,&m);
int i,x,y;
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
{
scanf("%d %d",&x,&y);
a[x][y]=1;a[y][x]=1;
}
search1(1);
printf("%d\n",minn);
return 0;
}
后来用dfs剪枝
思路大概是把每个学生放在教室里,检查是否符合条件。如果符合条件继续放入另外一个学生。然后回溯看看放入别的教室会不会更好一些。一开始我是写,如果之前的那些教室都放不了再考虑单独将他放一个教室,提交一发只过了60%的数据。后来改成了每一个学生都单独开一个教室,不论他和其他人的关系,看看值是否会有最小。过了。相当于两层递归。递归函数是个好东西。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,minn=inf;
int a[120][120],p[120],house[120][120];
void dfs(int studen,int room)
{
if(room>=minn)
return ;
if(studen==n+1)
{
minn=min(minn,room);return ;
}
for(int i=1;i<=room;i++)
{
int len=p[i];int k=0;
for(int j=1;j<=len;j++)
if(!a[studen][house[i][j]])
k++;
if(k==len)
{
house[i][++p[i]]=studen;
dfs(studen+1,room);
p[i]--;
}
}
house[room+1][++p[room+1]]=studen;
dfs(studen+1,room+1);
p[room+1]--;
return ;
}
int main()
{
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
memset(p,0,sizeof(p));
memset(house,0,sizeof(house));
int i,x,y;
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
dfs(1,0);
printf("%d\n",minn);
return 0;
}