zoukankan      html  css  js  c++  java
  • 【NOIP普及组】2016年模拟考试(9.3)——部落卫队

    四、部落卫队(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

    #------------------------------------------------------------------------------#


    先声明:我程序n=23就会超时……然而数据很水,所以过了,呵呵。


    此题也是深搜啦,很无耻地把原题解析先粘贴进来:

    1、深度优先搜索dfs

    2、本题是无向图,有边的2个点是双向连通,查找方案时,可以从编号小的开始往后查找不冲突的居民,每增加一个居民,保证该居民与这套方案已有的居民都不冲突。

    3、找到一套方案后,如果总居民数增多,就把这个方案保存下来。

    输出最大居民数的方案。


    然而根本不懂……下面正式思路:

    用个二维数组存敌对关系,然后递归就好,两个参数(x,y):此时是第几个“村民”,和“卫队”

    里已经有多少个多少“村民”了,边界:x>n,只要sum>maxn就保存数据。当然递归也是有条件的,要用个vis数组看看从第一个“村民”到当前“村民”有没有用过,如果用过,就要判断当前“村民”是不是他的仇人。

    记得当if不符合时一定要选下一个。


    程序:

    #include<cstdio>
    int n,m,maxn;
    int a[102][102],b[102],maxx[102];
    bool check(int k)
    {
    	for(int i=1;i<=k;i++)
    		if(b[i]==1&&a[i][k]==1)
    			return 0;
    	return 1;
    }//判断当前“村民”能不能用
    void wzy(int x,int sum)
    {
    	if(x>n)
    	{
    		if(sum>maxn)//如果大于就保存
    		{
    			maxn=sum;
    			for(int i=1;i<=n;i++)
    				maxx[i]=b[i];//其实可以直接memset,因为b无非就是1和0两种,可以复值的
    		}
    		return;//一定要return,否则就呵呵了
    	}
    	if(check(x))
    	{
    		b[x]=1;
    		wzy(x+1,sum+1);//选当前这个“村民”
    		b[x]=0;//记录数组要归零
    	}
    	wzy(x+1,sum);//不选当前这个“村民”
    }
    int main()
    {
    	freopen("tribe.in","r",stdin);
    	freopen("tribe.out","w",stdout);//文件输入输出
    	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;//存敌对关系,注意如果i和j为仇敌那么j和i一定为仇敌,所以正反都要存
    	}
    	wzy(1,0);//从第一个“村民”开始递归
    	printf("%d
    ",maxn);
    	for(int i=1;i<=n;i++)
    		printf("%d ",maxx[i]);//输出解
    	return 0;
    }
    

                                                                                                                                                                               By WZY

  • 相关阅读:
    Bootstrap表单验证插件bootstrapValidator使用方法整理
    去掉表格前符号
    消除float浮动的影响
    html 让一行文字居中
    java通过各种类型驱动连接数据库
    命令行查看端口
    You can't specify target table 'table' for update in FROM clause
    mysql 添加字段 修改字段为not null
    Js、Jquery定时执行(一次或者重复多次,取消重复)
    c# datetime与 timeStamp(unix时间戳) 互相转换
  • 原文地址:https://www.cnblogs.com/LinqiongTaoist/p/7203767.html
Copyright © 2011-2022 走看看