0
点赞
收藏
分享

微信扫一扫

11.3 剪枝思想(dfs)——【分考场(2017 年国赛)】

有点d伤 2022-02-27 阅读 44

文章目录

题目描述

n 个人参加某项特殊考试。

为了公平,要求任何两个认识的人不能分在同一个考场。

求是少需要分几个考场才能满足条件。

输入描述

输出描述

输入输出样例

输入:

5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5

输出:

4



最终代码

1. c/c++

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N][N];    //关系表
int p[N][N];    // 房间状态  ,第一个N代表第几个放假,第二个N代表该房间的人数
int num = N;    //考场数量
int n,m;

//x 代表当前安排了多少个人 cnt 代表考场数
void dfs(int x, int cnt) 
{     
    if (cnt >= num)   return;  //剪枝
    
    //已经安排了n个人
    if (x == n + 1)
    {         
        num = min(num, cnt);
        return;
    }
    
    
    int j, k;
    
     //枚举考场
    for (j = 1; j <= cnt; j++) 
    {   
        k = 0;
        while (p[j][k] && !a[x][p[j][k]])  //这个可变成a[p[j][k]][x]
            k++;                    //找到一个空位 并且与该考场人无关系
         
         //第j个考场没人,所以就把第x号人——>放在第j个考场   
        if (p[j][k] == 0)
            p[j][k] = x, dfs(x + 1, cnt), p[j][k] = 0; //继续下一考生
    }
    
    p[j][0] = x;
    dfs(x + 1, cnt + 1); // 如果所有房间都不满足条件,增加考场
    p[j][0] = 0;         //回溯
}


int main()
 {
    cin>>n>>m;
    for (int i = 1; i <= m; i++) 
    {
        int u,v;
        cin >> u >>v;
        a[u][v] = a[v][u] = 1;  //用矩阵表示两人的关系
    }
    dfs(1, 1);   //第一个人,第一个考场
    cout <<num;
    return 0;
}



过程理解

举报

相关推荐

0 条评论