POJ 2724 Purifying Machine(最大独立集)

【题目链接】 http://poj.org/problem?id=2724

【题目大意】

  出一些01串,如果一个位置为*,则表示这个位置可以填0和1,产生不同的串
  现在要匹配所有产生的串,你可以生成一些模式,生成的模式中最多可以有一个*,
  表示可以同时匹配这个位置上的0或1,问你至少生成几个串,就能匹配所有的串

【题解】

  我们先生成所有的串,我们对这些串进行相互比较,如果只有一位不同,
  那么就连一条边,构图完成之后求这个图的最大独立集就是答案。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector> 
using namespace std;
const int MAX_V=2000;
const int INF=0x3f3f3f3f;
int V,match[MAX_V];
vector<int> G[MAX_V];
bool used[MAX_V];
void add_edge(int u,int v){
    G[u].push_back(v);
    G[v].push_back(u);
}
bool dfs(int v){
    used[v]=1;
    for(int i=0;i<G[v].size();i++){
        int u=G[v][i],w=match[u];
        if(w<0||!used[w]&&dfs(w)){
            match[v]=u;
            match[u]=v;
            return 1;
        }
    }return 0;
}
int bipartite_matching(){
    int res=0;
    memset(match,-1,sizeof(match));
    for(int v=0;v<V;v++){
        if(match[v]<0){
            memset(used,0,sizeof(used));
            if(dfs(v))res++;
        }
    }return res;
}
void clear(){for(int i=0;i<V;i++)G[i].clear();}
const int MAX_N=30;
int N,M;
vector<int> op;
char s[MAX_N];
void solve(){
    op.clear();
    while(M--){
        scanf("%s",s);
        int t=0;
        for(int i=0;i<N;i++)if(s[i]=='1')t+=1<<(N-i-1);
        op.push_back(t);
        for(int i=0;i<N;i++)if(s[i]=='*')t+=1<<(N-i-1);
        op.push_back(t);
    }sort(op.begin(),op.end());
    op.erase(unique(op.begin(),op.end()),op.end());
    V=op.size(); clear();
    for(int i=0;i<V;i++){
        for(int j=i+1;j<V;j++){
            int diff=op[i]^op[j];
            if((diff&(-diff))==diff)add_edge(i,j);
        }
    }printf("%d
",V-bipartite_matching());
}
int main(){
    while(scanf("%d%d",&N,&M),N&&M)solve();
    return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/poj2724.html