Blue Bridge Cup Exams - minute examination room (DFS + pruning)

topic:

Here Insert Picture Description

input Output:

Here Insert Picture Description

analysis:

This problem to solve using a deep search, start one by one from the first individual allocation of classrooms, classroom allocation scheme is as follows: traverse existing classrooms, and then traverse all of the classroom to see if there is to be an individual with current people know the distribution of the classroom, the classroom if this person does not know, so we can present the person assigned to this classroom course, you can choose not to assign to the current classroom as assigned to the current classroom may not be optimal select, then we must use backtracking, backtracking purpose is to find the optimal solution, after traversing all classrooms that currently exist, there is a current strategy is to assign people to a new classroom, then this search to a situation, the following codes are explained in detail.

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#define INF 0x3f3f3f3f
using namespace std;

const int MAXN = 105;
int mat[MAXN][MAXN];  //mat[i][j]代表决定i和j之间是否认识
int cnt[MAXN];  //cnt[i]表示第i个教室的人数
int room[MAXN][MAXN]; //room[i][j]代表第i个教室中第j个人的编号
int n,m,ans;
bool flag;

void Dfs(int person,int num)   //person表示待分配的人 num表示当前教室数量
{
    if(num >= ans) return;    //剪枝 如果当前的教室数量大于ans 说明当前的选择肯定不是最优的
    if(person > n)   //如果person大于n 说明已经分配完了n个人 此时结果与ans相比较 取最优
    {
        ans = min(ans,num);
        return;
    }
    for(int i=0;i<num;++i)
    {
        flag = false;
        int allPep = cnt[i];
        for(int j=1;j<=allPep;++j)
            if(mat[person][room[i][j]])
            {
                flag=true;  //如果person和此教室中的任意一个人是朋友 则不满足条件
                break;
            }
        if(!flag)
        {
            cnt[i]++;  //表示person这个人加入到i教室中
            room[i][cnt[i]] = person;
            Dfs(person+1,num);
            cnt[i]--;   //回溯操作 因为person加入到当前的教室可能不是最优的
        }
    }
    cnt[num]++;  //表示上述可能没有满足教室分配的最优条件 那就重新开一个新教室
    room[num][cnt[num]] = person;
    Dfs(person+1,num+1);
    cnt[num]--;  //回溯 此处表示上一次的教室分配可能不是最优
}

int main()
{
    int a,b;
    ans = INF;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&a,&b);
        mat[a][b] = 1;
        mat[b][a] = 1;
    }
    Dfs(1,0);
    printf("%d\n",ans);
    return 0;
}
Published 61 original articles · won praise 7 · views 3635

Guess you like

Origin blog.csdn.net/weixin_42469716/article/details/104637914