题目描述
n 个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求最少需要分几个考场才能满足条件。
输入
第一行,一个整数 n(1<n<100),表示参加考试的人数。
第二行,一个整数 m,表示接下来有 m 行数据。
以下 m 行每行的格式为:两个整数 a,b,用空格分开 (1≤a,b≤n) 表示第 a 个人与第 b 个人认识(编号从 1 开始)。
输出
一行一个整数,表示最少分几个考场。
输入输出样例
输入1: 输出1:4
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
输入2: 输出2:6
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
思路
就是最小色数的模板,这里使用DFS完成。
STEP 1:输入,邻接表存图,计算度数。
STEP 2:定义一个索引数组,对索引数组按度数排序(避免破坏原度数数组)
STEP 3:进行DFS,详见代码。
代码
cpp#include<bits/stdc++.h> using namespace std; int n,m,r,c,deg[105],v[105],color[105],ans=INT_MAX; vector<int>edge[105]; bool cmp(int a,int b) { return deg[a]>deg[b]; } bool check(int u,int c) { for(int v:edge[u]) { if(color[v]==c) { return false; } } return true; } void dfs(int u,int cn)//v[u] cn:已使用的最大元素书 { if(cn>=ans)//当前色数已不小于最优解 { return; } if(u>n) { ans=min(ans,cn); return; } for(int c=1;c<=cn;c++)//尝试将当前顶点v[u]染成已有的颜色1..cn { if(check(v[u],c)) { color[v[u]]=c; dfs(u+1,cn); color[v[u]]=0; } } //都不行,使用新颜色 color[v[u]]=cn+1; dfs(u+1,cn+1); color[v[u]]=0; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; for(int i=1;i<=m;i++) { cin>>r>>c; edge[r].push_back(c); edge[c].push_back(r); deg[r]++,deg[c]++; } for(int i=1;i<=n;i++) { v[i]=i; } sort(v+1,v+1+n,cmp); dfs(1,0); cout<<ans; return 0; }运行结果

感谢阅读,我们下期再会。