码迷,mamicode.com
首页 > 系统相关 > 详细

UVA1663 Purifying Machine

时间:2015-08-29 21:40:13      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

模版集合个数减少是因为匹配串集合中没被匹配过的一对串匹配了。所以就是找一个二分图最大匹配。

代码里没有显式地建立二分图,可以假想两个集合X和Y,由于两个集合都会跑一遍,所以一个匹配会被算两次,返回的时候除以2就行了。

拾起几乎快忘了的匈牙利算法。。。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
const int N = 1<<maxn;


#define debug(x)\
bitset<16> bs(x);cout<<bs<<endl;

bool vis[N];
int match[N];
int dfsT[N], dfsTime, n, m, M,tot;

bool dfs(int u)
{
    for(int i = 0; i < n; i++){
        int v = u^(1<<i);
        if(vis[v] && dfsT[v] != dfsTime){
            dfsT[v] = dfsTime;
            if(!~match[v] || dfs(match[v])){
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}


int MaxMatch()
{
    memset(match,-1,sizeof(int)*M);
    memset(dfsT,0,sizeof(int)*M);
    dfsTime = 0;
    int ans = 0;
    for(int i = 0; i < M; i++){
        if(vis[i]){
            dfsTime++;
            if(dfs(i)) ans++;
        }
    }
    return ans>>1;
}


int read()
{
    M = 1<<n;
    memset(vis,0,sizeof(bool)*M);
    for(int i = 0; i < m; i++){
        int fg = -1,t = 0;
        scanf("\n");
        char ch;
        for(int j = 0;j < n; j++){
            ch = getchar();
            if(ch == *) fg = j;
            if(ch != 0) t |= 1<<j;
        }
        vis[t] = true;
        if(~fg) vis[t^(1<<fg)] = true;
    }
    int ret = 0;
    for(int i = 0; i < M; i++) if(vis[i]) ret++;
    return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&m),n){
        printf("%d\n",read()-MaxMatch());
    }
    return 0;
}

 

UVA1663 Purifying Machine

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4769790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!