二分图最大匹配 hdoj 1045「建议收藏」

二分图最大匹配 hdoj 1045

大家好,又见面了,我是全栈君。

题目:hdoj1045

题意:给出一个图。当中有 . 和 X 两种,. 为通路,X表示墙,在当中放炸弹,然后炸弹不能穿过墙。问你最多在图中能够放多少个炸弹?

分析:这道题目是在上海邀请赛的题目的数据简化版。数据水了,所以有非常多方法,这里讲二分图最大匹配,题目难点在于建图

想到用暴力过。可是事实证明我想多了。

然后又想到多重二分匹配,后来发现没有办法表示图中的行列中墙的阻隔,后来看了别人的建图,瞬间认为高大上。

建图,首先把每一行中的能够放一个炸弹的一块区域标记为同一个数字。数字不反复,然后列做同样的处理,即缩点。

缩点之后原图矩阵中每一个点都对用一个行数字和一个列数字,然后依照这两个数字进行二分匹配,其同样值仅仅取一个,得到的结果就是ans;

注意:每次推断增广的时候首先检查一下当前点有没有匹配。假设匹配就不用搜索,由于有多个值相应一个点,所以…

代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10;
#define Del(x,y) memset(x,y,sizeof(x))
char map[N][N];
int path[N][N];
int line[N][N],row[N][N],link[N],vis[N],vlink[N];
int n,cnt_row,cnt_line;
bool dfs(int x)
{
    for(int i=0;i<cnt_line;i++)
    {
        if(path[x][i]==1 && vis[i]==0)
        {
            vis[i]=1;
            if(link[i]==-1 || dfs(link[i]))
            {
                link[i]=x;
                vlink[x]=i;
                return true;
            }
        }
    }
    return false;
}
void solve()
{
    int ans=0;
    Del(link,-1);
    Del(vlink,-1);
    for(int i=0;i<cnt_row;i++)
    {
        if(vlink[i]==-1){  ///注意!标记找过的
            Del(vis,0);
            if(dfs(i))
                ans++;
        }
    }
    printf("%d\n",ans);
}
int main()
{
    //freopen("Input.txt","r",stdin);
    while(~scanf("%d",&n) && n)
    {
        char c;
        Del(map,0);
        for(int i=0;i<n;i++)
        {
            getchar();
            for(int j=0;j<n;j++)
                scanf("%c",&map[i][j]);
        }
        Del(line,-1);
        Del(row,-1);
        cnt_row=0,cnt_line=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(map[i][j] == '.' && row[i][j] == -1)
                {
                    for(int k = j; map[i][k] == '.' && k < n; ++k)
                        row[i][k] = cnt_row;
                    cnt_row++;
                }
                if(map[j][i] == '.' && line[j][i] == -1)
                {
                    for(int k = j; map[k][i] == '.' && k < n; ++k)
                        line[k][i] = cnt_line;
                    cnt_line++;
                }
            }
        }
        Del(path,0);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(map[i][j]=='.')
                    path[row[i][j]][line[i][j]]=1;
            }
        }
        solve();
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116075.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月26日 下午2:00
下一篇 2022年1月26日 下午3:00


相关推荐

  • ftp扫描软件下载_ftp扫描文件夹连接失败

    ftp扫描软件下载_ftp扫描文件夹连接失败不知道大家用过哪几种ftp扫描工具,是不是感觉都是大同小异的呢?其实市面上的ftp扫描工具功能都是差不多的,当然也还是有一点差别的,那一点的差别可能就是我们选择那一种ftp扫描工具的原因。不论怎么说,也都是要选择自己喜欢的ftp扫描工具来使用。第一款:IIS7服务器管理工具这款工具里面的ftp扫描工具体验感是比较好的,除了一般ftp扫描工具里面都有的批量管理,它还有很多自己设计的功能。可以说这就是它成功的关键。它还能够进行定时上传下载、定时备份和多任务同时进行。哦对,它还有自动更新的功能。IIS7服务

    2022年10月1日
    5
  • java 字符串中的每个单词的倒序输出「建议收藏」

    java 字符串中的每个单词的倒序输出「建议收藏」 面试题之–java 字符串中的每个单词的倒序输出1、输入一句英文,将句子倒序输出,忽略最后的标点。package shenjin;import java.util.Scanner;/** * 输入一句英文,将英文句子反转 * * @author LENOVO * */public class ReverseEnglish { public static vo…

    2022年6月13日
    36
  • 联合索引,回表,索引覆盖

    联合索引,回表,索引覆盖今天学习到了一点知识 来做一下笔记 建立联合索引时 为什么要关注列的顺序 mysql 建立联合索引有最左前置原则 在建立联合索引时 根据需求 where 子句中使用最频繁的一列放在最左边 如何理解联合索引中遵守的最左前置原则 mysql 默认的存储引擎是 InnoDB InnoDB 使用 B 树 B 树的数据项是复合的数据结构 是按照从左到右的顺序来建立搜索树的 比如当 AA BB CC 这样的数据来检索的时候 b 树会优先比较 AA 来确定下一步的所搜方向

    2026年3月26日
    2
  • 银行家算法程序c语言,银行家算法代码c语言编写[通俗易懂]

    银行家算法程序c语言,银行家算法代码c语言编写[通俗易懂]《银行家算法代码c语言编写》由会员分享,可在线阅读,更多相关《银行家算法代码c语言编写(4页珍藏版)》请在人人文库网上搜索。1、defineM100#includeintmaxMM,allocationMM,needMM,availableM;inti,j,n,m,r;voidtestout()/算法安全性的检测intk,flag,v=0;intworkM,aM;charfi…

    2022年6月4日
    32
  • Java 安全之Weblogic 2018-2628&2018-2893分析

    Java安全之Weblogic2018-2628&2018-2893分析0x00前言续上一个weblogicT3协议的反序列化漏洞接着分析该补丁的绕过方式,根据weblogic的补

    2021年12月12日
    45
  • zookeeper锁原理(如何实现分布式锁)

    zookeeper分布式锁的使用会涉及到分布式事物因此封装有@Transactional的方法如下:@OverridepublicBizReturn<String>insertMagicCubeVehicles(MagicCubeVehicleSaveRequestrequest)throwsBizException{ZooKeeperSes…

    2022年4月13日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号