• UVa 1663


    题面

    没有

    思路

    求一个若干个01串,其中可能带可以当成任意数字。那么我们考虑一下,*可以变成0或者1,那么并且在这个变形中这两个01串的奇偶性一定改变。那么我们可以建图,将所有在集合中的串和与奇偶性不同并且只改变一个位数的串(异或运算)当成是二分图的左右部,跑一遍匈牙利算出最大匹配,然后由于每个点会被重复,那么我们最终的答案就是集合中所有元素个数之和减去最大匹配数的二分之一。另外这个题01串的话,其实也有点提示你的意思,要学会多揣测出题人的意思。

    代码实现

    #include<cstdio>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    using namespace std;
    const int maxn=2100;
    int maze[maxn][maxn];
    int lefta[maxn];
    int t[maxn];
    char s[20];
    int n,m;
    int set[maxn];
    
    bool dfs (int u) {
        for (int v=0;v<maxn;v++) if (maze[u][v]&&t[v]==0) {
            t[v]=true;
            if (lefta[v]==-1||dfs (lefta[v])) {
                lefta[v]=u;
                return true;
            }
        }
        return false;
    }
    
    inline int hungry () {
        int ans=0;
        memset (lefta,-1,sizeof (lefta));
        for (int i=0;i<maxn;i++) {
            memset (t,0,sizeof (t));
            if (dfs (i)) ans++;
        }
        return ans;
    }
    
    int main () {
       while (cin>>n>>m) {
           if (n==0&&m==0) break;
           memset (maze,0,sizeof (maze));
           memset (set,0,sizeof (set));
    
           for (int i=1;i<=m;i++) {
               cin>>s;
               int temp=0;
               int flag=-1;
               for (int j=0;j<n;j++) {
                   if (s[j]=='1') temp|=(1<<j);
                   if (s[j]=='*')  flag=j;
               }
               set[temp]=1;
               if (flag!=-1) {
                   temp|=1<<flag;
                   set[temp]=1;
               }
           }
           int cnt;
           for (int i=0;i<maxn;i++) {
               
               if (set[i]) {
                   cnt++;
                   int temp;
                   for (int j=0;j<n;j++) {
                       temp=i^(1<<j);
                       if (set[temp]) maze[i][temp]=1;
                   }
               }
           }
           int ans=hungry ();
           cout<<cnt-hungry ()/2<<endl;
       }
        return 0;
    }       
    
  • 相关阅读:
    [刷题] 1016 部分A+B (15分)
    [刷题] 1022 D进制的A+B (20分)
    [刷题] 1021 个位数统计 (15分)
    [刷题] 1020 月饼 (25分)
    洛谷&BZOJ [POI2016]Korale
    反演魔术---二项式反演
    毒瘤养成记1: 如何卡hash
    多项式全家桶
    [CQOI]排序机械臂
    后缀自动机感性理解
  • 原文地址:https://www.cnblogs.com/hhlya/p/13372172.html
Copyright © 2020-2023  润新知