Oil Skimming

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2917    Accepted Submission(s): 1210

Problem Description

Thanks to a certain "green" resources company, there is a new profitable industry of oil skimming. There are large slicks of crude oil floating in the Gulf of Mexico just waiting to be scooped up by enterprising oil barons. One such oil baron has a special plane that can skim the surface of the water collecting oil on the water's surface. However, each scoop covers a 10m by 20m rectangle (going either east/west or north/south). It also requires that the rectangle be completely covered in oil, otherwise the product is contaminated by pure ocean water and thus unprofitable! Given a map of an oil slick, the oil baron would like you to compute the maximum number of scoops that may be extracted. The map is an NxN grid where each cell represents a 10m square of water, and each cell is marked as either being covered in oil or pure water.
 



Input

The input starts with an integer K (1 <= K <= 100) indicating the number of cases. Each case starts with an integer N (1 <= N <= 600) indicating the size of the square grid. Each of the following N lines contains N characters that represent the cells of a row in the grid. A character of '#' represents an oily cell, and a character of '.' represents a pure water cell.
 



Output

For each case, one line should be produced, formatted exactly as follows: "Case X: M" where X is the case number (starting from 1) and M is the maximum number of scoops of oil that may be extracted.
 



Sample Input

1
6
......
.##...
.##...
....#.
....##
......
 



Sample Output

Case 1: 3
 



Source

 
每个‘#’向其左边和上边的‘#’连边,然后跑最大匹配
//2017-08-26
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int N = ;
const int M = ;
int head[N], tot;
struct Edge{
int to, next;
}edge[M]; void init(){
tot = ;
memset(head, -, sizeof(head));
} void add_edge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++; edge[tot].to = u;
edge[tot].next = head[v];
head[v] = tot++;
} int n;
int matching[N];
int check[N];
string G[];
int id[][], idcnt; bool dfs(int u){
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(!check[v]){//要求不在交替路
check[v] = ;//放入交替路
if(matching[v] == - || dfs(matching[v])){
//如果是未匹配点,说明交替路为增广路,则交换路径,并返回成功
matching[u] = v;
matching[v] = u;
return true;
}
}
}
return false;//不存在增广路
} //hungarian: 二分图最大匹配匈牙利算法
//input: null
//output: ans 最大匹配数
int hungarian(){
int ans = ;
memset(matching, -, sizeof(matching));
for(int u = ; u < idcnt; u++){
if(matching[u] == -){
memset(check, , sizeof(check));
if(dfs(u))
ans++;
}
}
return ans;
} int main()
{
std::ios::sync_with_stdio(false);
//freopen("inputG.txt", "r", stdin);
int T, kase = ;
cin>>T;
while(T--){
cin>>n;
init();
idcnt = ;
for(int i = ; i < n; i++){
cin>>G[i];
for(int j = ; j < n; j++){
if(G[i][j] == '#'){
id[i][j] = idcnt++;
if(i->= && G[i-][j] == '#')
add_edge(id[i][j], id[i-][j]);
if(j->= && G[i][j-] == '#')
add_edge(id[i][j], id[i][j-]);
}
}
}
cout<<"Case "<<++kase<<": "<<hungarian()<<endl;
} return ;
}

HDU4185(KB10-G 二分图最大匹配)的更多相关文章

  1. POJ2239 Selecting Courses(二分图最大匹配)

    题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...

  2. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  3. 【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

    学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二 ...

  4. [HDU] 2063 过山车(二分图最大匹配)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2063 女生为X集合,男生为Y集合,求二分图最大匹配数即可. #include<cstdio> ...

  5. [POJ] 1274 The Perfect Stall(二分图最大匹配)

    题目地址:http://poj.org/problem?id=1274 把每个奶牛ci向它喜欢的畜栏vi连边建图.那么求最大安排数就变成求二分图最大匹配数. #include<cstdio> ...

  6. POJ - 1422 Air Raid 二分图最大匹配

    题目大意:有n个点,m条单向线段.如今问要从几个点出发才干遍历到全部的点 解题思路:二分图最大匹配,仅仅要一条匹配,就表示两个点联通,两个点联通仅仅须要选取当中一个点就可以,所以有多少条匹配.就能够减 ...

  7. zoj1654 Place the Robots 二分图最大匹配

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 将每一行的包含空地的区域编号 再将每一列的包含空地的区域编号 然 ...

  8. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

  9. 二分图最大匹配:匈牙利算法的python实现

    二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是 ...

随机推荐

  1. Windows 网卡超过序列

    以前连接过别的网络,现在重新装网已经排到"网络连接9"了,连以前起过的wifi名称(ssid)都变成"*** 3"了,怎么把以前的清空呢? 这是解决办法: wi ...

  2. mybatis 插件原理

    [传送门]:mybatis 插件原理

  3. PHP 中 var_export、print_r、var_dump 调试中的区别

    1.output basic type 代码 $n = "test"; var_export($n); print_r($n); var_dump($n); echo '----- ...

  4. D13——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D13 20180918内容纲要: 堡垒机运维开发 1.堡垒机的介绍 2.堡垒机的架构 3.小结 4.堡垒机的功能实现需求 1 堡垒机的介绍 百度百科 随着信息安 ...

  5. Git for Windows之分支管理、分支合并、解决分支冲突

    分支是在稳定版本出现bug的情况下,通过分支技术,在保证稳定版本稳定的情况,修改稳定版本的(差异下载的,速度极快,不同于SVN等技术,会将所有的代码下载到本地)副本,通过合并,解决冲突,最后回归到稳定 ...

  6. django2笔记:路由path语法

    django2笔记:路由path语法 9月23,Django 发布了2.0a1版本,这是一个 feature freeze 版本,如果没有什么意外的话,2.0正式版不会再增加新的功能了.按照以往的规律 ...

  7. Selenium自动化测试Python五:WebDriver设计模式

    WebDriver 设计模式 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver 自动化框架的设计,着重使用Page Object设计模式,以及使用HTML测 ...

  8. 全网最详细的用pip安装****模块报错:Could not find a version that satisfies the requirement ****(from version:) No matching distribution found for ****的解决办法(图文详解)

    不多说,直接上干货! 问题详情 这个问题,很普遍.如我这里想实现,Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库. 见,我撰写的 全网最 ...

  9. MYSQL用户权限管理(Grant,Revoke)

    MySQL可以为不同的用户分配严格的.复杂的权限.这些操作大多都可以用SQL指令Grant(分配权限)和Revoke(回收权限)来实现. Grant可以把指定的权限分配给特定的用户,如果这个用户不存在 ...

  10. git命令小记

    1.git之tag git标签分为轻量级(lightweight)标签和含标注(annotated)标签.轻量级标签一般用于不会改变的分支,含标注的标签包含详细的信息. 轻量级标签: git tag ...