poj 2724 Purifying Machine 二分图最大匹配

Description

Mike is the owner of a cheese factory. He has 2 N 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

刚开始,我错了好些次,最后想想,原来是由于符合条件的写成了2^n,这是错的,3和5就不是,他们都符合2的倍数,但符合2的倍数
不一定 符合它
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 2550


bool Map[maxn][maxn];
bool Flag[maxn];
int Mark[maxn];
int lx[maxn];


bool Find(int x,int n)
{
    int i;
    for(i=1;i<=n;i++)
    {
        if(!Map[x][i]||Flag[i])
            continue;
        Flag[i]=true;
        if(!Mark[i]||Find(Mark[i],n))
        {
            Mark[i]=x;
            return true;
        }
    }
    return false;
}
int change(char *str,int n)
{
    int i;
    int t=0;
    for(i=0;i<n;i++)
    {
        t*=10;
        t+=(str[i]-'0');
    }
    return t;
}
int main()
{
    int n,m;
    char str[55];
    int i,j,k;
    int p;
    int stand;
    int t;
    int a[15]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
    while(scanf("%d%d",&n,&m),(n+m))
    {
        p=1;
        for(i=1;i<=m;i++)
        {
            scanf("%s",str);
            for(j=0;j<n;j++)
                if(str[j]=='*')
                {
                    k=j;
                    break;
                }
            if(j<n)
            {
                str[k]='0';
                stand=change(str,n);
                lx[p++]=stand;
                str[k]='1';
                stand=change(str,n);
                lx[p++]=stand;
            }
            else
            {
                stand=change(str,n);
                lx[p++]=stand;
            }
        }
        sort(lx+1,lx+p);
        stand=unique(lx+1,lx+p)-lx-1;
        for(i=1;i<=stand;i++)
            for(j=1;j<=stand;j++)
            {
                t=abs(lx[i]-lx[j]);
                for(k=0;k<=9;k++)
                    if(t==a[k])
                        break;
                if(k<=9)
                    Map[i][j]=true;
                else
                    Map[i][j]=false;
            }
        memset(Mark,0,sizeof(Mark));
        int Count=0;
        for(i=1;i<=stand;i++)
        {
            memset(Flag,false,sizeof(Flag));
            if(Find(i,stand))
                Count++;
        }
        printf("%d\n",stand-Count/2);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值