PREV-53 分考场

问题描述

  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

分析:dfs深度搜索,遍历目前已有的房间,判断这个人是否可以放入,若是,则放入,继续dfs。遍历完可以把他放到新的房间里再dfs。找出所需最少的房间。注意剪枝。

#include<iostream>
#include<vector>
using namespace std;
bool is_friend[100][100];
int n,m;
int minroom=1000;
int theroom[102][102];//不同房间的人
int cnt[102];//不同房间的人的数量
void dfs(int person,int roomnum)
{
    if(roomnum>=minroom)
    {//剪枝
        return;
    }
    if(person>n)
    {
        minroom=min(minroom, roomnum);
        return;
    }
    for(int i=1;i<=roomnum;i++)
    {
        int flag=0;
        for(int j=1;j<=cnt[i];j++)
        {
            if(is_friend[person][theroom[i][j]]==true)
            {
                flag=1;
                break;
            }
        }
        if(flag==0)//可以放在这个屋子里
        {
            theroom[i][++cnt[i]]=person;
            dfs(person+1,roomnum);
            cnt[i]--;
        }
    }
    //放到新的屋子里
    theroom[roomnum+1][++cnt[roomnum+1]]=person;
    dfs(person+1,roomnum+1);
    cnt[roomnum+1]--;
    return;
}
int main()
{
    cin>>n>>m;
    int a,b;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        is_friend[a][b]=is_friend[b][a]=true;
    }
    dfs(1,0);
    cout<<minroom<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41242380/article/details/88718019