部落卫队

来源:互联网 发布:消防知识知多少作文 编辑:程序博客网 时间:2024/06/10 03:23

 部落卫队

时间限制: 1 Sec  内存限制: 128 MB


题目描述

原始部落byteland中的居民们为了争夺有限的资源,经常发生冲突。几乎每个居民都有他的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍,并保证队伍中任何2 个人都不是仇敌。给定byteland部落中居民间的仇敌关系,编程计算组成部落卫队的最佳方案。

输入

第1行有2个正整数n和m,表示byteland部落中有n个居民,居民间有m个仇敌关系。居民编号为1,

2,…,n。接下来的m行中,每行有2个正整数u和v,表示居民u与居民v是仇敌。

输出

第1行是部落卫队的顶人数;文件的第2行是卫队组成x i,1≤i≤n,xi =0 表示居民i不在卫队中,xi=1表示居民i在卫队中。


样例输入

7  101  21  42  42  32  52  63  53  64  55  6

样例输出

31 0 1 0 0 0 1
思路:(暴力)判断一下每一个人之前是否有敌对的,如果没有就把他加入进去,如果有就不加入。
代码如下
#include<cstdio>#include<cstring>#define met(a,b) memset((a),(b),sizeof(a)) using namespace std;int a[100][100];//敌对关系 int b[100];//标记人 ,防止重复 int ans;//最大人数 int Max[100];//卫队成员 int n,m;bool check(int k) //检查K之前是否有敌对关系 {    for(int i=1;i<=k;i++)    {        if(b[i]==1&&a[i][k]==1)//如果人重复且有敌对的人         return false;    }    return true;}int dfs(int x,int sum){    if(x>n)    {        if(sum>ans)//求最大值,并记录相应的人         {            ans=sum;            for(int i=1;i<=n;i++)            Max[i]=b[i];        }        return 0;    }     if(check(x))//检验当前人员之前是否存在敌对     {        b[x]=1;//标记一下         dfs(x+1,sum+1);//选当前村民         b[x]=0;    }    dfs(x+1,sum);//不选当前村民 }int main(){    met(a,0);met(b,0);met(Max,0);    scanf("%d %d",&n,&m);    for(int i=1;i<=m;i++)//敌对关系建立     {        int x,y;        scanf("%d %d",&x,&y);        a[x][y]=1;        a[y][x]=1;      }    dfs(1,0);    printf("%d\n",ans);//输出卫队最大人数     for(int i=1;i<=n;i++)    printf("%d ",Max[i]);}


原创粉丝点击