NOIP2016年普及组模拟考试(9.3) 4.部落卫队
2016-09-08 13:47
357 查看
一、原题
4.部落卫队(tribe.cpp)
【题目描述】
原始部落byteland中的居民们为了争夺有限的资源,经常发生冲突。几乎每个居民都有他的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍,并保证队伍中任何2 个人都不是仇敌。 给定byteland部落中居民间的仇敌关系,编程计算组成部落卫队的最佳方案。【输入】
第1行有2个正整数n和m,表示byteland部落中有n个居民 (n<=100),居民间有m个仇敌关系。接下来的m行中,每行有2个正整数u和v,表示居民u与居民v是仇敌。(居民编号为1,2,...,n)【输出】
第1行是部落卫队的最多人数。第2行是卫队组成xi,1<=i<=n,xi=0表示居民i不在卫队中,xi=1表示居民i在卫队中。【样例输入】
7 10 1 2 1 4 2 4 2 3 2 5 2 6 3 5 3 6 4 5 5 6
【样例输出】
3 1 0 1 0 0 0 1
二、分析
这道题要用广度优先搜索dfs,本题类似于无向图,有边的2个点是双向连通,查找方案时,可以从编号小的开始往后查找不冲突的居民,每增加一个居民,保证该居民与这套方案已有的居民都不冲突。然后找到一套方案后,如果总居民数增多,就把这个方案保存下来。最后,输出最大居民数的方案。三、源代码
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int vis[103],p[103],sum,m; struct tribe{ int b[103],k; }a[103]; void dfs(int i,int s){ if(i==m+1){ if(s>sum){//选取最优解并保存到p数组 memcpy(p,vis,sizeof(vis)); sum=s; } return; } if(!vis[i]){//没有访问 vis[i]=1; for(int j=0;j<a[i].k;j++) vis[a[i].b[j]]+=2; dfs(i+1,s+1); vis[i]=0; for(int j=0;j<a[i].k;j++) vis[a[i].b[j]]-=2; } dfs(i+1,s);//继续广搜dfs } int main() { freopen("tribe.in","r",stdin); freopen("tribe.out","w",stdout);//文件输入输出 int n,x,y,i; cin>>m>>n; for(i=1;i<=n;a[x].b[a[x].k++]=y,i++) cin>>x>>y; dfs(1,0);//广度优先搜索dfs printf("%d\n",sum); for(i=1;i<=m;i++)//输出各项 if(p[i]==1) printf("1 "); else printf("0 "); }
相关文章推荐
- 【NOIP普及组】2016年模拟考试(9.3)——部落卫队
- NOIP2016年普及组模拟考试(9.3) 5.母亲的牛奶
- NOIP2016年普及组模拟考试(9.3) 2.笨笨的西瓜种植
- 【NOIP普及组】【DFS】2016年模拟考试(9.3)——母亲的牛奶
- 【NOIP普及组】2016年模拟考试(9.3)——笨笨的西瓜种植
- NOIP2016年普及组模拟考试(9.3) 1.笨笨玩游戏
- 【NOIP普及组】2016年模拟考试(9.3)——笨笨玩游戏
- NOIP2016年普及组模拟考试(9.3) 3.笨笨连线游戏
- 【NOIP普及组】2016年模拟考试(11.5)——火柴棒等式
- 【2016普及组模拟考试】04 搜索 tribe(部落卫队)
- 【NOIP普及组】2016模拟考试(10.29)——海港的船只
- 【NOIP普及组】2016模拟考试(11.8)——公路
- 【NOIP普及组】2016模拟考试(10.29)——排座椅
- 【NOIP普及组】2016模拟考试(10.29)——摆花
- 【NOIP普及组】2016模拟考试(11.1)——生活大爆炸版石头剪刀布
- [考试] [NOIP模拟] [2017-11-01] 极其良(e)心的一次考试
- 【模拟】Vijos P1771 瑞士轮 (NOIP2011普及组第三题)
- 2016.08.19【初中部 NOIP普及组 】模拟赛题解
- 1109 NOIP 模拟考试
- 【模拟 集合】[NOIP2008普及组]立体图 tyvj1009