[精]poj2724

Purifying Machine

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5027   Accepted: 1455

Description

Mike is the owner of a cheese factory. He has 2N cheeses and each cheese is given a binary number from 00...0 to 11...1. To keep his cheese free from viruses, he made himself a purifying machine to clean virus-infected cheese. As a talented programmer, his purifying machine is built in a special way. His purifying machine has N switches, each switch has three states, 1, 0 and *. An operation of this machine is a cleaning action according to the states of the N switches. During one operation, at most one switch can be turned to state *, which can substitute for either 1 or 0. When the machine is turned to a specific state, an operation will clean all the cheeses with corresponding binary numbers. For example, if N equals 6 and the switches are turned to 01*100, the cheeses numbered 010100 and 011100 are under operation by the machine.

One day, Mike‘s machine was infected. When
Mike found out, he had already done some operations and the cheeses operated by
this infected machine were infected too. He cleaned his machine as quickly as he
could, and now he needs to clean the infected cheeses with the minimum number of
operations. If a cheese is infected, cleaning this cheese with the machine one
or more times will make this cheese free from virus again; but if a cheese is
not infected, operation on this cheese will make it go bad.

Now given
the infected operations Mike has done, you need to find out the minimum number
of operations that must be performed to clean all the infected cheeses without
making any clean cheese go bad.

Input

There are several test cases. Each test case starts
with a line containing two numbers N and M (1 <= N <= 10, 1 <= M <=
1000). N is the number of switches in the machine and M is the number of
infected operations Mike has done. Each of the following M lines contains a
switch state of the machine. A test case with N = M = 0 ends the input and
should not be processed.

Output

For each test case, output one line containing an
integer, which is the minimum number of operations Mike needs to do.

Sample Input

3 3
*01
100
011
0 0

Sample Output

2

Source

Beijing 2005

题意:

题意:迈克有一台可以净化奶酪的机器,用二进制表示净化的奶酪的编号。但是,在某些二进制串中可能包含有‘*‘。例如01*100,‘*‘其实就代表可以取0,1两种情况--> 010100 和011100。现在由于迈克不小心,他以同样的方式弄脏了某些奶酪,问你最少用多少次操作就可以把弄脏的奶酪全净化好。(没有被弄脏过的奶酪不能净化。弄脏过的奶酪可以多次净化。)

思路:

也就是给你一些不同的(判重之后)二进制串,每个串可以通过1次操作净化,也可以把两个只有1位不同的串通过1次操作联合净化.要我们求最少的操作次数.

我们把所有串按其中1的个数和是奇还是偶分成左右两个点集.

对于任意两个串,如果他们只有1位不同,那么就在他们之间连接一条无向边.(这两个串一定分别属于不同的点集)

由于串的总数是固定的,且一个串可以通过单独净化也可以通过联合净化.而我们向让净化的次数最少,我们自然想联合净化(即一次可以净化两个串)的次数尽量多了. 那么我们最多可以进行多少次联合净化呢? 这个数值==我们建立二分图的最大匹配边数.(想想是不是,因为一个串最多只能被净化一次)

假设总的不同串有n个,我们建立二分图的最大匹配数(即联合净化最大次数)为ans,那么我们总共需要n-ans次净化即可.(想想为什么)

当然本题也可以不用把串特意分成左右点集(本程序实现就是用的这种方式:未分左右点集),我们只需要把原图翻倍,然后求翻倍图的最大匹配数ans,最后用n-ans/2即可.

这个题中有很多位运算的有意思的东西

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3000+50;
int uN,vN;
int g[N][N];
int link[N];
int used[N];
int num[N];
int dfs(int u){
    for(int v=0;v<vN;v++)//顶点编号从0开始的
        if(g[u][v]&&!used[v]){
            used[v]=1;
            if(link[v]==-1||dfs(link[v])){
                link[v]=u;
                return 1;
            }
        }
    return 0;
}
int hungary(){
    int res=0;
    memset(link,-1,sizeof(link));
    for(int u=0;u<uN;u++){
        memset(used,0,sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}
int main(){
    int n,m;
    char str[50];
    while(scanf("%d%d",&n,&m)==2&&(m+n)){
        memset(g,0,sizeof(g));
        memset(num,0,sizeof(num));
        int cnt=0;
        while(m--){
            cnt++;
            scanf("%s",&str);
            int pos=-1;
            for(int i=0;i<n;i++){
                if(str[i]==‘*‘){pos=i;continue;}
                num[cnt]|=(str[i]-‘0‘)<<i;
            }
            if(pos!=-1){
                cnt++;
                num[cnt]=(num[cnt-1]|(1<<pos));
            }
        }
        sort(num+1,num+cnt+1);
        num[0]=-1;
        int i,j;
        for(j=0,i=1;i<=cnt;i++){
            if(num[j]!=num[i])
                num[++j] = num[i];
        }
        cnt=j;
        for(i=1;i<=cnt;i++)
            for(j=1;j<=cnt;j++){
                int c=num[i]^num[j];
                if(c&&((c&(c-1))==0))g[num[i]][num[j]]=1;
            }
        uN=vN=2050;
        int ans=cnt-hungary()/2;
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-17 14:12:07

[精]poj2724的相关文章

【转】《从入门到精通云服务器》第六讲—OpenStack基础

前五期的<从入门到精通云服务器>受到了广泛好评,收到留言,有很多读者对云计算相关的技术非常感兴趣.应观众要求,我们这期要安利一条纯技术内容.准备好瓜子.花生,随小编一起进入OpenStack 基础知识大讲堂吧. 了解OpenStack OpenStack 是最火的开源软件之一,活跃度呈指数级别上升:它是一组开源项目,诞生之初是由两个项目组成,目前十几个项目:它是一个云操作系统,OpenStack is a cloud operating system that … OpenStack 管理的资

只想把技术做好,维持一份可观的收入,就精专一门;有创业想法,就全栈

做全栈开发(前端和后端)好还是全端开发(前端和Android应用开发)好?哪个前景和钱景发现比较好,对以后的发展! 1. 有创业想法,就全栈.只想把技术做好,维持一份可观的收入,就精专一门 2. 全栈对自己的优势不大吗?好多公司都不认同,特别是HR,普遍的观点是,会的多,就很难专精. 3. 大公司是一个靠分工增加工作效率的机构,无论你全栈,还是全端,对公司来说都只用你的一部分技能.但是薪资可是要比一般的人高一些,所以很多HR都忽悠你说全会的就没法专精.先全栈,后全端.别信那些HR忽悠. 4. 有

MVVM大比拼之vue.js源码精析

VUE 源码分析 简介 Vue 是 MVVM 框架中的新贵,如果我没记错的话作者应该毕业不久,现在在google.vue 如作者自己所说,在api设计上受到了很多来自knockout.angularjs等大牌框架影响,但作者相信 vue 在性能.易用性方面是有优势.同时也自己做了和其它框架的性能对比,在这里.今天以版本 0.10.4 为准 入口 Vue 的入口也很直白: ? 1 var demo = new Vue({ el: '#demo', data: { message: 'Hello V

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字段的类型以及相关属性elasticsearch会根据json源数据的基础类型猜测你想要的字段映射,将输入的数据转换成可搜索的索引项,mapping就是我们自己定义的字段数据类型,同时告诉elasticsearch如何索引数据以及是否可以被搜索 作用:会让索引建立的更加细致和完善 类型:静态映射和动态

面试必看:java面试考点干货精讲视频教程

Java作为目前比较火的计算机语言之一,连续几年蝉联最受程序员欢迎的计算机语言榜首,因此每年新入职Java程序员也数不胜数.很多java程序员在学成之后,会面临着就业的问题.在面试的过程中,面试技巧是一项很重要的能力. 今天要给大家介绍的是一个java经典面试套路精讲视频教程,需要的朋友可以看看,希望能帮助到大家! 课程目录: 第一节. String Stringbuffer Stringbuilder 深度解析第二节. 完美回答面试题Int 与Integer的区别第三节. 以数据结构挖掘集合面

第9天:CSS精灵图

今天重点学习了CSS精灵图. "CSS精灵",英语css sprite,所以也叫做"CSS雪碧"技术.是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,然后利用css的背景定位来显示需要显示的图片部分. css精灵有什么优点,就是减少了http请求.比如4张小图片,原本需要4个http请求.但是用了css精灵,小图片变为了一张图,http请求只有1个了. 用ps选框工具选择需要显示的部分,点开信息面板,width和height就是盒子的宽高,鼠标

前端网站资源精编!!

不要吝啬你的赞美喜欢就点个赞 目录: 1-------- 走进前端2-------- jQuery3-------- CSS4-------- Angularjs5-------- ES66-------- React7-------- 移动端API8-------- avalon9-------- Requriejs10-------- vue11-------- Seajs12-------- Less,sass13-------- Markdown14-------- D315------

[BZOJ 2729][HNOI2012]排队(排列组合+高精)

Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) Solution 好像必须写压位高精的QAQ 先排n名男生,插空,讨论两名老师插在两个不同的空里的情况和先排在一起再在中间插一名女生的情况 #include<iostream> #include<cstdio> #include<cstring> #include&

精灵云受邀参加2017全球云计算开源峰会

作者:精灵云 由工业和信息化部指导.中国信息通信研究院主办.云计算开源产业联盟承办的"全球云计算开源峰会"将于2017年4月19日-20日在国家会议中心举行.本次峰会将聚焦虚拟化和OpenStack.容器.大数据.运维等开源技术和产业,以及开源治理等方面内容. 作为企业级容器云服务专家,精灵云受邀参加本次全球云计算开源峰会,除参展本次峰会外,还将在金融行业论坛做相关主题的演讲报告. Ghostcloud精灵云成立于2015年,是成都高新区重点扶持企业,也是国内首批从事容器虚拟化研发的企