蓝桥杯[2017年第八届真题]分考场 (图着色问题)

题目描述

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

 

思路:暴力深搜 但是不要去遍历所用房间个数(超时) 姿势要对 直接对可能房间个数取最小值即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define ll long long int
using namespace std;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
int G[107][107];
int col[107];
int n,m;
int ans;
void dfs(int id,int top){
    if(top>=ans) return ;
    if(id==n+1){
        ans=min(ans,top);
        return ;
    }
    for(int i=1;i<=top;i++){
        bool f=1;
        for(int j=1;j<id;j++){
            if(col[j]==i&&G[id][j]){
                f=0;
                break;
            }
        }
        if(!f) continue;
        col[id]=i;
        dfs(id+1,top);
        col[id]=0;
    }
    col[id]=top+1;
    dfs(id+1,top+1);
    col[id]=0;
    return ;
}
int main(){
    //ios::sync_with_stdio(false);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        G[a][b]=1;
        G[b][a]=1;
    }
    ans=inf;
    dfs(1,0);
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2019-03-19 19:33  WAKBGAN  阅读(281)  评论(0编辑  收藏  举报