部落卫队
题目描述
原始部落 byteland 中的居民们为了争夺有限的资源,经常发生冲突。几乎每个居民都有他的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍,并保证队伍中任何 222 个人都不是仇敌。
给定 byteland 部落中居民间的仇敌关系,编程计算组成部落卫队的最佳方案。若有多种方案可行,输出字典序最大的方案。
输入格式
第 111 行有 222 个正整数 nnn 和 mmm,表示 byteland 部落中有 nnn 个居民,居民间有 mmm 个仇敌关系。居民编号为 1,2,⋯ ,n1,2, \cdots ,n1,2,⋯,n。接下来的 mmm 行中,每行有 222 个正整数 uuu 和 vvv,表示居民 uuu 与居民 vvv 是仇敌。
输出格式
第 111 行是部落卫队的人数;文件的第 222 行是卫队组成 xix_ixi,1≤i≤n1 \le i \le n1≤i≤n,xi=0x_i=0xi=0 表示居民 iii 不在卫队中,xi=1x_i=1xi=1 表示居民 iii 在卫队中。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int m, n, a[105]; 4 int ch[105][105];//标记两个人是否是仇敌关系 5 int x[105], tot = 0, s = 0; 6 void dfs(int k) 7 { 8 if(k > n) 9 { 10 if(s <= tot) 11 return; 12 tot = s; 13 for(int j = 1; j <= n; j++) 14 a[j] = x[j]; 15 return; 16 } 17 int check = 1; 18 for(int t = 1; t < k; t++) 19 if(ch[t][k] && x[t]) 20 { 21 //如果现在已经选择的人中有人与第k个人为仇敌关系,则第k个人不能选 22 check = 0; 23 break; 24 } 25 if(check) 26 {//如果第k个人可以选 27 x[k] = 1; 28 s++; 29 dfs(k + 1);//尝试选第k个人的情况 30 s--; 31 x[k] = 0; 32 } 33 dfs(k + 1);//尝试不选第k个人的情况 34 return; 35 } 36 int main() { 37 scanf("%d%d", &n, &m); 38 int u, v; 39 for(int i = 1; i <= m; i++) 40 { 41 scanf("%d%d", &u, &v); 42 ch[u][v] = 1;//标记u和v的仇敌关系 43 ch[v][u] = 1; 44 } 45 dfs(1);//从第一个人开始搜索 46 printf("%d\n", tot); 47 for(int i = 1; i <= n; i++) 48 printf("%d ", a[i]); 49 return 0; 50 }

浙公网安备 33010602011771号