Exámenes del azul del puente - sala de examen minutos (DFS) + poda

tema:

Aquí Insertar imagen Descripción

Entrada y salida:

Aquí Insertar imagen Descripción

análisis:

Este problema a resolver mediante una búsqueda profunda, se inicia una a una de la primera asignación individual de las aulas, esquema de asignación de clase es el siguiente: Traverse aulas existentes, y luego travesía toda la clase para ver si ha de ser un individuo con corriente la gente sabe la distribución de la sala de clase, la clase si esta persona no sabe, por lo que podemos presentar a la persona asignada a este curso en el aula, se puede optar por no asignar a la clase actual asignado a la clase actual puede no ser óptima seleccionamos, entonces tenemos que usar el retroceso, retroceso propósito es encontrar la solución óptima, después de atravesar todas las aulas que existen actualmente, hay una estrategia actual es la gente asigna a un nuevo salón de clases, entonces esta búsqueda a una situación, los siguientes códigos se explican en detalle.

código:

#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;
}
Publicado 61 artículos originales · ganado elogios 7 · vistas 3635

Supongo que te gusta

Origin blog.csdn.net/weixin_42469716/article/details/104637914
Recomendado
Clasificación