HDU1045(二分图经典建模)

Fire Net

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8338    Accepted Submission(s): 4796

Problem Description

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

Input

The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.‘ indicating an open space and an uppercase ‘X‘ indicating a wall. There are no spaces in the input file.

Output

For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.

Sample Input

4

.X..

....

XX..

....

2

XX

.X

3

.X.

X.X

.X.

3

...

.XX

.XX

4

....

....

....

....

0

Sample Output

5

1

5

2

4

Source

Zhejiang University Local Contest 2001

/*
ID: LinKArftc
PROG: 1045.cpp
LANG: C++
*/

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-8
#define randin srand((unsigned int)time(NULL))
#define input freopen("input.txt","r",stdin)
#define debug(s) cout << "s = " << s << endl;
#define outstars cout << "*************" << endl;
const double PI = acos(-1.0);
const double e = exp(1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
typedef long long ll;

const int maxn = 20;

struct Node {
    char cha;
    int idx, idy;
} node[maxn][maxn];
int mp[maxn][maxn];
int n, uN, vN;
int linker[maxn];
bool vis[maxn];

bool dfs(int u) {
    for (int v = 1; v <= vN; v ++) {
        if (!vis[v] && mp[u][v]) {
            vis[v] = true;
            if (linker[v] == -1 || dfs(linker[v])) {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

int hungry() {
    memset(linker, -1, sizeof(linker));
    int ret = 0;
    for (int i = 1; i <= uN; i ++) {
        memset(vis, 0, sizeof(vis));
        if (dfs(i)) ret ++;
    }
    return ret;
}

int main() {

    while (~scanf("%d", &n) && n) {
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) scanf(" %c", &node[i][j].cha);
        }
        uN = 0;
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                if (node[i][j].cha == ‘X‘) continue;
                if (j == 1 && node[i][j].cha == ‘.‘) uN ++;
                else if (node[i][j].cha == ‘.‘ && node[i][j-1].cha == ‘X‘) uN ++;
                node[i][j].idx = uN;
            }
        }
        vN = 0;
        for (int j = 1; j <= n; j ++) {
            for (int i = 1; i <= n; i ++) {
                if (node[i][j].cha == ‘X‘) continue;
                if (i == 1 && node[i][j].cha == ‘.‘) vN ++;
                else if (node[i][j].cha == ‘.‘ &&node[i-1][j].cha == ‘X‘) vN ++;
                node[i][j].idy = vN;
            }
        }
        memset(mp, 0, sizeof(mp));
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                if (node[i][j].cha == ‘X‘) continue;
                mp[node[i][j].idx][node[i][j].idy] = 1;
            }
        }
        printf("%d\n", hungry());
    }

    return 0;
}
时间: 2024-10-05 05:07:37

HDU1045(二分图经典建模)的相关文章

bzoj1823 JSOI2010 满汉全席 2-SAT 经典建模

这个题其实我一开始看完没有想到2-SAT 而思路巧妙,编程复杂度低也是我选这个题的原因,在3h4t的赛制中非常适合(好像是病句..) 具体的来说就是,因为每种材料都有两个选择,那就是做成满式或者是汉式 那么我们可以考虑,在信息学奥赛中,只有两种选择的有哪些.. 看来只有二分图和2-SAT了? 然后我们注意到,每个选择是互相排斥的,那么这不正好符合2-SAT的性质么?--每个布尔变量只能是成立或者是不成立,这与满式汉式这好一样. 好那如果你已经想到2-SAT了以后这题基本就出来了 因为本题根本不用

杭电HDU ACM Uncle Tom&#39;s Inherited Land*(二分图匹配 建模)

Uncle Tom's Inherited Land* Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2496    Accepted Submission(s): 1028 Special Judge Problem Description Your old uncle Tom inherited a piece of land f

POJ 1149--PIGS 【最大流 &amp;&amp; 处理重边 &amp;&amp; 经典建模】

PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18123   Accepted: 8246 Description Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock any pighouse because he doesn't have the keys. Customers come t

图论常用算法之二 算法模板及建模总结

寒假的第二周,弥补了一下图论算法.在这里做一下总结,主要针对近期学到的一些建模技巧,同时也非常感谢有朋友能够给出图论算法相关的精彩讲解或者知识链接. 算法总结: 欧拉回路问题:判断图是否存在欧拉回路或者欧拉通路,输出一条欧拉回路. 学习Fleury算法输出一条欧拉回路. 1 /* G是连通无向图,则称经过G的每条边一次并且仅一次的路径为 2 欧拉通路,起点和终点是同一个顶点称为欧拉回路,具有欧拉回路的 3 无向图为欧拉图. 4 依次有有向欧拉通路,有向欧拉回路,有向欧拉图 5 定理:连通图G仅有

二分图最大匹配[网络流]

题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 建模: s--1-->X--1-->Y--1-->t 注意:边的数量 PS:本题比hungary快了5倍 // // main.cpp // 二分图dinic // // Created by Candy on 29/11/2016. // Copyri

BZOJ 1433 假期的宿舍 二分图匹配

这道题目不难,二分图匹配建模比较明显.加油吧!相信自己.(自己写的,好开心,40毫秒,比ccz略快). 尽管算法模版是抄一本书上的,但这次很明显我是背出来的.不算抄. 1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 #include<queue> 5 #include<cstring> 6 #define rep(i,j,k) for(int i = j; i <=

二分图之poj2446

题目:poj2446 题意:给出一个m*n的矩阵,其中有的地方有坑,然后用1*2的纸片去覆盖图,纸片不能重复,能够把出了坑的地方其他全部覆盖的话输出YES,否则NO 分析:有一道二分图经典题目,当然难点还是建图,一直没有思路,早上来忽然想到可以用(i-1)*m+j 吧矩阵中每个点转化为一个数,然后相邻连接起来建图,匈牙利,但是不知道为什么不对?求大神解释.还是理解不够深. 很多人都是按其奇偶性建图的,因为要用1*2的纸片覆盖,那么两个值(i+j)必然一个奇数一个偶数,然后分别给图中的奇数偶数点依

SPOJ 839 Optimal Marks 最小割 经典 按位建图

胡伯涛论文中的一题,经典建模,由于二进制每一位异或不会相互影响,所以我们把问题转换模型,按位处理. 即已知一些点的标号0/1(还有些可以自己任意改),和一些边,边权定义为两端点标号的异或,要求边权和最小的标号方案. 我们联想到最小割求的是从源到汇容量最小的边权和. 建图: 标号为1的和源点相连,容量INF,标号为0的和汇点相连,容量INF,这些边是不能割掉的(这些点标号已经明确) 原图相连的边,连边,容量为1.(若将此边割掉,则两端点一个为0,一个为1,割为1) 跑完最大流后,在残量网络中dfs

的二分图poj2446

称号:id=2446">poj2446 意甲冠军:给定一个m*n矩阵,在有些地方坑,然后1*2本文叠加,反复.可以把出了坑的地方其它所有覆盖的话输出YES,否则NO 分析:有一道二分图经典题目,当然难点还是建图,一直没有思路,早上来忽然想到能够用(i-1)*m+j 吧矩阵中每一个点转化为一个数,然后相邻连接起来建图,匈牙利,可是不知道为什么不正确?求大神解释.还是理解不够深. 非常多人都是按其奇偶性建图的,由于要用1*2的纸片覆盖,那么两个值(i+j)必定一个奇数一个偶数.然后分别给图中的