洛谷【P1692】——部落卫队

来源:互联网 发布:淘宝货源外国 编辑:程序博客网 时间:2024/04/30 12:49

P1692 部落卫队
洛谷

题目描述

原始部落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在卫队中。

输入输出样例

输入样例#1:
7 10
1 2
1 4
2 4
2 3
2 5
2 6
3 5
3 6
4 5
5 6
输出样例#1:
3
1 0 1 0 0 0 1
说明

60%数据:n<=20,m<=100

所有数据:n<=100,m<=3000

暴搜+剪枝

#include<iostream>#include<cstring>#include<cstdio>using namespace std;int a[1001][1001],b[1000]={0},c[1000];int max1=0,s,m;void shuchu();int n;int dfs(int);int main(){    int i1,x,y;    cin>>n>>m;    for(i1=1;i1<=m;i1++)    {        cin>>x>>y;        a[x][y]=1;   //第x个人的仇敌是第y个人         a[y][x]=1;   //第y个人的仇敌是第x个人     }    dfs(1);   cout<<max1<<endl;   for (int i1=1;i1<=n;i1++)  //输出        cout<<c[i1]<<" ";    fclose(stdin);fclose(stdout);    return 0;}int dfs(int k){    int i,j,c=0,v=0,z;    for (i=1;i>=0;i--) if((v==0)&&(i==0)) break; //这里是优化,判断如果上一次该元素没能入队,那第二次判断不进队后的循环就没有意义了,这里作为一次优化。     else    {   z=0;c=0;        if (i==1) //判断这次进队         {        for (j=1;j<=k-1;j++)         if (b[j]==1) if(a[j][k]==1) {c=1;break;} //判断能否进队,与之前已经进队的元素是否有冲突           if (c==0)           {              b[k]=1; //标记该进队元素               s++;   //计数加一               v=1;//确定此次进队了,标记一下              z=1;  //确定此次进队了,标记一下           }}           if (k<n) dfs(k+1);   //如果没到边界,递归深搜,进行下一个元素         else if (s>max1&&k==n) {shuchu();max1=s;}  //否则则所有元素已经判断进队完毕,则判断此次计数是否最大值,并交换,覆盖最优解         if (z==1) s--;  //回溯          b[k]=0;  //回溯         }}void shuchu(){    for(int i=1;i<=n;i++)    c[i]=b[i]; //覆盖最优解 }
2 0
原创粉丝点击