• UVa 1663 净化器


    https://vjudge.net/problem/UVA-1663

    题意:

    给m个长度为n的模板串,每个模板串包含字符0,1和最多一个星号"*",其中星号可以匹配0或1。例如,模板01*可以匹配010和011两个串。改写这个模板集合,使得模板的个数最少。

    思路:

    一个模板只能匹配两个字符串。所以要减少次数的话,我们就要尽量把字符串一一配对,这样每两个字符串都可以用一个模板串来表示。那么这就很明显的是求二分图的最大匹配。下面的代码中因为重复匹配了,所以最后需要除2。

     1 #include<iostream> 
     2 #include<string>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 2100;
     9 int n, m;
    10 int c[maxn];
    11 int g[maxn][maxn];
    12 int vis[maxn];
    13 int match[maxn];
    14 
    15 int dfs(int x)
    16 {
    17     for (int i = 0; i < maxn; i++)
    18     {
    19         if (g[x][i] && !vis[i])
    20         {
    21             vis[i] = 1;
    22             if (match[i] == -1 || dfs(match[i]))
    23             {
    24                 match[i] = x;
    25                 return 1;
    26             }
    27         }
    28     }
    29     return 0;
    30 }
    31 
    32 int main()
    33 {
    34     char s[15];
    35     ios::sync_with_stdio(false);
    36     //freopen("D:\txt.txt", "r", stdin);
    37     while (~scanf("%d%d",&n,&m)&&(n||m))
    38     {
    39         memset(c, 0, sizeof(c));
    40         memset(g, 0, sizeof(g));
    41         for (int i = 0; i < m; i++)
    42         {
    43             int num= 0;
    44             int pos = -1;
    45             scanf("%s", s);
    46             for (int j = 0; j < n; j++)
    47             {
    48                 if (s[j] == '1')  num |= 1 << j;
    49                 else if (s[j] == '*')   pos = j;
    50             }
    51             c[num] = 1;
    52             if (pos != -1)
    53             {
    54                 num |= 1 << pos;
    55                 c[num] = 1;
    56             }
    57         }
    58         int cnt = 0;
    59         for (int i = 0; i < maxn; i++)
    60         {
    61             if (c[i])
    62             {
    63                 cnt++;
    64                 for (int j = 0; j < n; j++)
    65                 {
    66                     int temp = i ^ (1 << j);
    67                     if (c[temp])  g[i][temp] = 1;
    68                 }
    69             }
    70         }
    71         int tot = 0;
    72         memset(match, -1, sizeof(match));
    73         for (int i = 0; i < maxn; i++)
    74         {
    75             memset(vis, 0, sizeof(vis));
    76             tot += dfs(i);
    77         }
    78         cout << cnt - tot / 2 << endl;
    79     }
    80 }
  • 相关阅读:
    天天写业务代码,如何成为技术大..niu?
    2021年12月PHP面试题总结
    同事乱用 Redis 卡爆,我真是醉了...
    如何合理的面试审问面试官:
    进制转换
    Is there a difference between table.class tr, th and table .class tr, th?
    ubuntu中安装notepadqq
    VPDN
    OpenAppFilter 自定义特征库
    Tcping详细使用教程
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6516893.html
Copyright © 2020-2023  润新知