hdoj1045--Fire Net(二分图 转化 )

Fire Net

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

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

Recommend

We have carefully selected several similar problems for
you:  1175 1067 1258 1053 1026

二分图行列匹配, 主要是处理过程;

#include <cstdio>
#include <cstring>
using namespace std;
char Ap[5][5];
int Gra[5][5], vis[5], dis[5];
int dx[5], dy[5], left[5], right[5];
int n;
struct Node{
    int x, y;
}a[5][5];
void Printf(){
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            printf("%c", Ap[i][j]);
        }
        printf("\n");
    }
}
int x, y;
bool Search(int a){
    for(int i = 1; i <= y; i++){
        if(Gra[a][i] && !vis[i]){
            vis[i] = 1;
            if(!dis[i] || Search(dis[i])){
                dis[i] = a;
                return true;
            }
        }
    }
    return false;
}
int main(){
    while(scanf("%d", &n) != EOF && n){
        for(int i = 0; i < n; i++)
        {
            getchar();
            for(int j = 0; j < n; j++)
                scanf("%c", &Ap[i][j]);
        }
        x = y = 0;
        for(int i = 0; i < n; i++)   //行列匹配;
            for(int j = 0; j < n; j++)
            {
                if(Ap[i][j] == ‘.‘)
                {
                    if(j == 0 || Ap[i][j-1] == ‘X‘){
                        x++;        /***********************/
                    }
                    a[i][j].x = x;
                }
                if(Ap[j][i] == ‘.‘)
                {
                    if(j == 0 || Ap[j-1][i] == ‘X‘){
                        y++;       /***********************/
                    }
                    a[j][i].y = y;
                }
            }
        memset(Gra, 0, sizeof(Gra));
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                if(Ap[i][j] == ‘.‘){
                    int u = a[i][j].x;
                    int v = a[i][j].y;
                    Gra[u][v] = 1;
                }
            }
        int ans = 0;
        memset(dis, 0, sizeof(dis));
        for(int i = 1; i <= x; i++)
        {
            memset(vis, 0, sizeof(vis));
            if(Search(i))
                ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
} 

暴搜;

#include <cstdio>
int n, cnt;
char map[5][5];
bool Build(int row, int col){
    int i, j;
    for(int i = row; i >= 0; i--){
        if(map[i][col] == ‘O‘)
            return false;
        if(map[i][col] == ‘X‘)
            break;
    }
    for(int i = col; i >= 0; i--){
        if(map[row][i] == ‘O‘)
            return false;
        if(map[row][i] == ‘X‘)
            break;
    }
    return true ;
}
void Dfs(int i, int num){
    if(i == n*n){
    //    printf("%d %d\n", i, num);
        if(num > cnt)
            cnt = num;
        return;
    }
    else{
        int row = i / n;
        int col = i % n;
        if(map[row][col] == ‘.‘ && Build(row, col)){
            map[row][col] = ‘O‘;
            Dfs(i+1, num+1);
            map[row][col] = ‘.‘;
        }
        Dfs(i+1, num);
    }
}
int main(){
    while(scanf("%d", &n), n){
        cnt = 0;
        for(int i = 0; i < n; i++)
            scanf("%s", map[i]);
        Dfs(0, 0);
        printf("%d\n", cnt);
    }
    return 0;
}
时间: 2024-08-02 14:19:40

hdoj1045--Fire Net(二分图 转化 )的相关文章

HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)

(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配,那就直接匹配:如果Y中已经没有可以和x匹配的点(包括可以匹配的点已经被其他的x匹配),那就让已经匹配的y的原配x'寻找其他可以匹配的y’,并将y和x匹配,最后,统计出匹配的对数 (详细了解的话,可以看看这位的博客:https://blog.csdn.net/sunny_hun/article/de

HDU1045 Fire Net —— 二分图最大匹配

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12920    Accepted Submission(s): 7840 Problem Description Suppose that we have a squa

HDU 1045 Fire Net 二分图Bipartite题解

本题可以使用DFS直接爆搜出答案,不过这样类型的题目其实是个二分图的题解. 这个二分图,难不在Hungary算法,而是难在于建图.需要挺高的抽象思维的. 建图: 1 把同一行不被X分开的格子标同一个号码,被X分开的标下一个号码,这样做是为了缩点,不需要把所有的格子都分开标号,而且可以更方便建个更加小的图. 2 同理把同一列的格子标号 3 然后判断相同一个格子的行标号和列标号是有路径的,其他不在同一个格子的都是没有路径的. 4 这样就等于以行标号和列标号作为左右顶点,构建成一个二分图了 然后使用H

[ZJOI2007]矩阵游戏——非常漂亮的二分图转化

题意: 小 Q 是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个 N×N 黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作: 行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色) 列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色) 游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色. 对于某些关卡,小 Q 百思不得其解,以致他开始怀疑这些关卡是不是根本就

链接分析算法之:SALSA算法

SALSA算法的初衷希望能够结合PageRank和HITS算法两者的主要特点,既可以利用HITS算法与查询相关的特点,也可以采纳PageRank的“随机游走模型”,这是SALSA算法提出的背景.由此可见,SALSA算法融合了PageRank和HITS算法的基本思想,从实际效果来说,很多实验数据表明,SALSA的搜索效果也都优于前两个算法,是目前效果最好的链接分析算法之一. 从整体计算流程来说,可以将SALSA划分为两个大的阶段:首先是确定计算对象集合的阶段,这一阶段与HITS算法基本相同:第二个

hdu 1045 &amp;&amp; zoj 1002 Fire Net(DFS &amp;&amp; 二分图匹配)

Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7958    Accepted Submission(s): 4542 Problem Description Suppose that we have a square city with straight streets. A map of a city is a

【转化为二分图判定问题的难题】

关键词:并查集,二分图,搜索. 例题一: CodeForces-85E:Guard Towers 题意:给定平面上N个点(N<=5000),以及N个点的坐标.现在可以把每个点染成红色或者蓝色.求最小化同色点的最大距离,且求出相应的方案数. 思路:二分答案L,把距离大于等于L的连边,然后判定是否是二分图. 对于求方案数,这个先不管它. (当然,最优的解法是转化为切比雪夫距离,复杂度极低,这个也先不管它.) 例题二: CodeForces-164D:Minimum Diameter 题意:给定平面上

uva12083 二分图 求最大独立集 转化为求最大匹配 由题意推出二分图

这题大白书例题 : Frank 是一个思想有些保守的高中老师,有一次,他需要带一些学生出去旅行,但又怕其中一些学生在旅途中萌生爱意.为了降低这种事情的发生概率,他决定确保带出去的任意两个学生至少要满足下面4条中的一条 1 身高相差大于40 2 性别相同 3 最喜欢的音乐属于不同的类型 4 最喜欢的体育比赛相同 任务帮组Frank挑选尽量多的学生,使得任意两个学生至少满足上述条件中的一条. 解  将不能同时去的人连一条边 就变成求最大独立集,即选择尽量多的节点,使得任意两个节点不相邻.|最大独立集

hdoj--1045&lt;dfs&amp;二分图最大匹配&gt;(这里是dfs解法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目描述: 在矩阵中放车,车可四面攻击,矩阵中有墙,可以防止攻击,给出墙的位置,输出最多可以放多少车: 题目要点:dfs&二分图最大匹配(匈牙利算法)(这里是dfs) 本题在一开始作的时候陷入了贪心的漩涡,写出来的以为是dfs.但实际上是谈心,而且贪心在这里是错误的:(贪心算法的应用范围比较窄,多数情况下是错误的) 然后发现了dfs与贪心的不同:贪心算法是每次放置车的方法都是固定,实际上并没有