zoukankan      html  css  js  c++  java
  • BZOJ4554

    原题链接

    Description

    给出一个n×m(n,m50)的地图,地图上有空地、软石头和硬石头。求在这张地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到。炸弹能炸到的范围是该炸弹所在的一行和一列,炸弹的威力可以穿透任意个软石头,但是不能穿透硬石头。

    Solution

    把每行/每列以硬石头为界划分成若干个部分,如图:
    划分
    则每个空地都是一个横着的部分和一个竖着的部分的交,每个部分里最多只能有一个炸弹。
    于是把每个部分看成图中的一个顶点;若两个部分交于一块空地则连一条边。显然这是一个二分图,因为竖着的部分之间不会有边,横着的部分之间也不会有边。该图中的一组匹配就表示放了一个炸弹在这两个部分的交上,那么答案就是这个二分图的最大匹配数。

    最多划分为nm个部分,这些部分之间最多有nm条边。时间复杂度为O(n2m2)

    Code

    //[Tjoi2016&Heoi2016]游戏
    #include <cstdio>
    #include <cstring>
    int const N=3e3;
    int n,m; char map[N][N];
    int cnt,row[N][N],col[N][N];
    bool ed[N][N];
    int link[N]; bool used[N];
    bool match(int u)
    {
        for(int v=1;v<=cnt;v++)
            if(ed[u][v]&&!used[v])
            {
                used[v]=true;
                if(!link[v]||match(link[v])) {link[v]=u; return true;}
            }
        return false;
    }
    int Hungary()
    {
        int res=0;
        for(int i=1;i<=cnt;i++)
        {
            memset(used,0,sizeof used);
            if(match(i)) res++;
        }
        return res;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%s",map[i]+1);
        for(int i=1;i<=n;i++)
            for(int j1=1;j1<=m;j1++)
            {
                if(map[i][j1]=='#'||row[i][j1]) continue;
                cnt++;
                for(int j2=j1;j2<=m&&map[i][j2]!='#';j2++) row[i][j2]=cnt;
            }
        for(int j=1;j<=m;j++)
            for(int i1=1;i1<=n;i1++)
            {
                if(map[i1][j]=='#'||col[i1][j]) continue;
                cnt++;
                for(int i2=i1;i2<=n&&map[i2][j]!='#';i2++) col[i2][j]=cnt;
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(map[i][j]=='*') ed[row[i][j]][col[i][j]]=true;
        printf("%d
    ",Hungary());   
        return 0;
    }

    P.S.

    HDU1045是这道题的简化版。

  • 相关阅读:
    兄弟连新版ThinkPHP视频教程2.ThinkPHP 3.1.2 MVC模式和URL访问
    兄弟连新版ThinkPHP视频教程1.ThinkPHP 3.1.2 介绍及安装
    【算法】高效计算n的m次方
    linux下解压.zip压缩包出现乱码的问题解决
    马哥linux笔记--重定向
    JavaScript的基本知识
    repeater做删除前弹窗询问
    网页中图片路径错误时显示默认图片方法
    添加分页
    javascript类型转换
  • 原文地址:https://www.cnblogs.com/VisJiao/p/8485758.html
Copyright © 2011-2022 走看看