NKOJ-1524 柯南开锁

17 篇文章 0 订阅

P1524柯南开锁
时间限制 : 10000 MS 空间限制 : 65536 KB
问题描述

    柯南决定深入OIBH组织内部, 一探虚实.他经过深思熟虑, 决定从OIBH组织大门进入...........
    OIBH组织的大门有一个很神奇的锁.锁是由M*N个格子组成, 其中某些格子凸起(灰色的格子). 每一次操作可以把某一行或某一列的格子给按下去.

    如果柯南能在组织限定的次数内将所有格子都按下去, 那么他就能够进入总部. 但是OIBH组织不是吃素的, 他们的限定次数恰是最少次数
    请您帮助柯南计算出开给定的锁所需的最少次数.

输入格式

第一行 两个不超过100的正整数N, M表示矩阵的长和宽
以下N行 每行M个数 非0即1 1为凸起方格

输出格式

一个整数 所需最少次数

样例输入

4 4
0000
0101
0000
0100

样例输出

2

你明明应该很虚,然而你却选择从大门堂而皇之地撬锁进去

题解

约束条件

当你按下某一个点(x,y)时,你可以选择按行,也可以选择按列
但是,当你按下这一行时,这一列上就少了一个点
同理,按下这一列时,这一行上也少了一个点

例如

0 1 1 0
0 1 0 0
0 0 0 0

我们按下第1行第2列的行时,第一行全部都变为了0,同时第二列也少了一个需要按下去的点

那么约束条件就是在x行和y列上连边
当你连上某条边时,代表的就是那一行或那一列全部的点全部被按了
那么x点连接的其他边或y点连接的其他边就无需再连了

然后求最大匹配即可

解疑

为什么按下一个点(x,y)这一行(x)和这一列(y)都不需要再按了呢??

说的意会一点就是
这就是求最小点覆盖集

仔细解释一下
当我们求到了最小点覆盖集的时候
有点的每一行/每一列都被覆盖了
那么我们可以理解为把每一行/每一列都按下去,这一定是一个解

即:即使我们不选择最优解,把有点的每一行都按下去都一定是一个解

那么,由于我们求的是最小点覆盖,所以这个得到的就一定是最优解

换句话说,我们求到的题目的解也必须要满足覆盖有点的每一行/每一列,才是一个正常解

附上代码

#include <iostream>
#include <cstdio>
using namespace std;

int n,m,res=0;
char maps[123][123];
int all=0,star[234],nxt[12345],ent[12345];
int fath[234],went[234];

void add(int s,int e)
{
    nxt[++all]=star[s];
    star[s]=all;
    ent[all]=e;
}

bool find (int s,int t)//求最大匹配
{
    int bian,e;
    for(bian=star[s],e=ent[bian];bian;bian=nxt[bian],e=ent[bian])
    if(went[e]!=t)
    {
        went[e]=t;
        if(!fath[e]||find(fath[e],t))
        {
            fath[e]=s;
            return 1;
        }
    }
    return 0;
}

int main()
{
    scanf("%d%d\n",&n,&m);
    for(int a=1;a<=n;a++)scanf("%s",&maps[a]);
    for(int a=1;a<=n;a++)
    for(int b=0;b<m;b++)
        if(maps[a][b]=='1')
            add(a,n+b+1);//构二分图
    for(int i=1;i<=n+m;i++)res+=find(i,i);
    printf("%d",res);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值