二分图匹配,注意判重~
代码:
#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; }