zoukankan      html  css  js  c++  java
  • 蓝桥杯 试题 历届试题 分考场 dfs+回溯

    问题描述
      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
    • 解题思路:依次安排学生,尝试所有可能的考场(满足不认识考场所有人或者将该学生放入新考场) + 回溯,取所有可能最小考场。(加上简单判断剪枝)
    • 解题代码:
     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std;
     4 
     5 const int Max_N = 100;
     6 const int INF = 100000;
     7 
     8 //输入
     9 int n,m; 
    10 
    11 bool acq[Max_N+1][Max_N+1] = {false,};//acq[i][j]=true i与j考生认识 
    12 vector<int> room[Max_N]; //考场
    13 int res = INF; //保存最优解 
    14 
    15 //id:学生编号 num:当前考场最大编号 
    16 void dfs( int id, int num )
    17 {
    18     if( num>=res ){
    19         return; //剪枝 
    20     }    
    21     if( id==n+1 ){//安排完所有学生 
    22         res = num; //大于的都被剪枝了
    23         return; 
    24     }
    25     
    26     for( int i=0; i<num; i++ )
    27     { 
    28         bool flag = false;
    29         for( int j=0; j<room[i].size(); j++ )
    30         {
    31             int id_ = room[i][j];
    32             if( acq[id][id_] ){
    33                 flag = true;
    34                 break;
    35             }
    36         }
    37         if( !flag )
    38         {//满足条件 不认识该考场所有学生 
    39             room[i].push_back( id );
    40             dfs( id+1, num );
    41             room[i].pop_back(); //回溯 
    42         }
    43     }
    44     
    45     //新开考场 
    46     room[num].push_back( id );
    47     dfs( id+1, num+1 );
    48     room[num].pop_back(); 
    49 } 
    50 
    51 void solve()
    52 {
    53     dfs( 1,0 );
    54     
    55     printf("%d
    ",res);
    56 }
    57 
    58 int main()
    59 {
    60     scanf("%d%d",&n,&m);
    61     while( m-- )
    62     {
    63         int u,v;
    64         scanf("%d%d",&u,&v);
    65         acq[u][v] = acq[v][u] = true;
    66     }
    67     
    68     solve();
    69     
    70     return 0;
    71 }
     
  • 相关阅读:
    多线程编程(14) 多线程同步之 WaitableTimer (等待定时器对象)
    多线程编程(17) 多线程同步之 WaitableTimer (等待定时器对象)[续三]
    多线程编程(13) 多线程同步之 Event (事件对象)
    一个关于 absolute 关键字的小练习
    [新功能]在个人Blog页面显示最新评论
    asp.net页面中hmtl注释的问题
    [征询意见]博客园准备租用更好的服务器
    [公告]博客园分页浏览功能改进
    [公告]博客园新服务器测试
    [公告]博客园建立了人才求职区
  • 原文地址:https://www.cnblogs.com/w-like-code/p/13945922.html
Copyright © 2011-2022 走看看