二分图匹配,注意判重~
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
const int maxn=1<<11;
int n,m,link[maxn];
bool vis[maxn],y[maxn];
vector<int> g[maxn];
void Init()
{
for(int i=0;i<(1<<n);i++)
g[i].clear();
}
bool find(int x)
{
for(int i=0;i<g[x].size();i++)
if(!y[g[x][i]])
{
y[g[x][i]]=1;
if(link[g[x][i]]==-1||find(link[g[x][i]]))
{
link[g[x][i]]=x;
return true;
}
}
return false;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n+m))
{
Init();
memset(vis,0,sizeof(vis));
memset(link,-1,sizeof(link));
for(int i=0;i<m;i++)
{
char str[20];
scanf("%s",str);
int pos=-1,val=0;
for(int j=0;j<n;j++)
{
if(str[j]=='*')
pos=j;
else if(str[j]=='1')
val|=1<<j;
}
vis[val]=1;
if(pos!=-1)
vis[val|(1<<pos)]=1;
}
int cnt=0;
for(int i=0;i<(1<<n);i++)
if(vis[i])
{
cnt++;
for(int j=i+1;j<(1<<n);j++)
if(vis[j])
{
int c=i^j;
if(c&&!(c&(c-1)))
{
g[i].push_back(j);
g[j].push_back(i);
}
}
}
int ans=0;
for(int i=0;i<(1<<n);i++)
if(vis[i])
{
memset(y,0,sizeof(y));
if(find(i))
ans++;
}
printf("%d\n",cnt-ans/2);
}
return 0;
}