4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=4554

题解:

如果没有硬石头的话,就是’*‘点对应的行列建边,然后跑最大匹配

硬石头什么作用?它可以让同一行或同一列存在不只一个炸弹,因此我们可以将一个硬石头的上下拆成两列,左右拆成两行,然后就可以用经典的做法来跑最大匹配了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6
 7 const int maxn = 55;
 8 const int maxs = 2555;
 9 int n, m;
10
11 char str[maxn][maxn];
12 int _x[maxn][maxn], _y[maxn][maxn];
13 int _r, _c;
14 vector<int> G[maxs];
15
16 int lef[maxs], _t[maxs];
17 bool match(int u) {
18     for (int j = 0; j < G[u].size(); j++) {
19         int v = G[u][j];
20         if (!_t[v]) {
21             _t[v] = 1;
22             if (lef[v]==-1 || match(lef[v])) {
23                 lef[v] = u;
24                 return true;
25             }
26         }
27     }
28     return false;
29 }
30
31 int BM() {
32     memset(lef, -1, sizeof(lef));
33     for (int i = 0; i < _r; i++) {
34         memset(_t, 0, sizeof(_t));
35         match(i);
36     }
37     int ret = 0;
38     for (int i = 0; i < _c; i++) {
39         if (lef[i] != -1) ret++;
40     }
41     return ret;
42 }
43
44 void init() {
45     for (int i = 0; i < maxs; i++) G[i].clear();
46 }
47
48 int main() {
49     while (scanf("%d%d", &n, &m) == 2 && n) {
50         init();
51         for (int i = 0; i < n; i++) scanf("%s", str[i]);
52         _r = 0, _c = 0;
53         for (int i = 0; i < n; i++) {
54             for (int j = 0; j < m; j++) {
55                 if (str[i][j] == ‘#‘) _r++;
56                 else if (str[i][j] == ‘*‘) _x[i][j] = _r;
57             }
58             _r++;
59         }
60         for (int j = 0; j < m; j++) {
61             for (int i = 0; i < n; i++) {
62                 if (str[i][j] == ‘#‘) _c++;
63                 else if (str[i][j] == ‘*‘) _y[i][j] = _c;
64             }
65             _c++;
66         }
67         for (int i = 0; i < n; i++) {
68             for (int j = 0; j < m; j++) {
69                 if (str[i][j] == ‘*‘) {
70                     G[_x[i][j]].push_back(_y[i][j]);
71                 }
72             }
73         }
74         printf("%d\n", BM());
75     }
76     return 0;
77 }
78
79 /*
80 4 4
81 #***
82 *#**
83 **#*
84 xxx#
85 */
时间: 2024-09-29 10:12:07

4554: [Tjoi2016&Heoi2016]游戏 二分图匹配的相关文章

【BZOJ4554】[Tjoi2016&amp;Heoi2016]游戏 二分图最大匹配

[BZOJ4554][Tjoi2016&Heoi2016]游戏 Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张 地图上最多能放上多少个炸弹能使得任意两个炸弹之间不会互相炸到.炸弹能炸到的范围是该炸弹所在的一行和一 列,炸弹的威力可以穿透软石头,但是不能穿透硬石头.给定一张n*m的网格地图:其中*代表空地,炸弹的威力

二分图 BZOJ4554 [Tjoi2016&amp;Heoi2016]游戏

4554: [Tjoi2016&Heoi2016]游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 579  Solved: 350[Submit][Status][Discuss] Description 在2016年,佳缘姐姐喜欢上了一款游戏,叫做泡泡堂.简单的说,这个游戏就是在一张地图上放上若干个炸弹,看 是否能炸到对手,或者躲开对手的炸弹.在玩游戏的过程中,小H想到了这样一个问题:当给定一张地图,在这张 地图上最多能放上多少个炸弹能使得

bzoj 1059: [ZJOI2007]矩阵游戏 二分图匹配

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1891  Solved: 919[Submit][Status] Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵

[SCOI2010][BZOJ1854] 游戏|二分图匹配|匈牙利算法|并查集

1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 3018  Solved: 1099[Submit][Status][Discuss] Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使用一次. 游戏进行到最后,lxhgww遇到了终极boss

[luogu1640 SCOI2010]连续攻击游戏 (二分图匹配)

[传送门] (https://www.luogu.org/problemnew/show/P1640) Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使用一次.游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害.也就是说一开始

BZOJ 1854 游戏(二分图匹配或并查集)

此题的二分图匹配做法很容易想,就是把属性当做s集,武器当做t集,如果该武器拥有该武器则连一条边. 那么答案就是求该二分图的最大前i个匹配.将匈牙利算法改一改,当前找不到增广路就break. 但是过这个题需要常数优化,不能每次都fillchar一遍used数组.可以用队列将使用的used点加入,然后需要初始化的时候弹出即可. # include <cstdio> # include <cstring> # include <cstdlib> # include <i

[bzoj4554] [Tjoi2016&amp;Heoi2016]游戏

传送门 网络流的题目做的还真不是很多,这种题目很容易看出是网络流,但就是不怎么会建图. 如果没有硬石头,就是一个经典的二分图匹配问题. 但是有硬石头存在,由于硬石头对前后左右的状态不会发生传递,因此,可以以硬石头为界建立联通块. 然后跑网络流就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<

HDU1281-棋盘游戏-二分图匹配

先跑一个二分图匹配,然后一一删去匹配上的边,看能不能达到最大匹配数,不能这条边就是重要边 1 /*--------------------------------------------------------------------------------------*/ 2 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <ctype.h> 7 #i

cogs660 矩阵游戏 二分图匹配

填坑--链接:http://cogs.pro/cogs/problem/problem.php?pid=660 题意:给出一个矩阵,有黑白双色,问是否可以使主对角线全为黑色. 不能不说现在越来越垃圾了--眼看错误都看不出来-- 这道题显然可以网络流瞎切,但是我们考虑到填坑向需求,所以我们用二分图做它.把每一行看做$x$节点,列看做$y$节点,每个黑节点看做一条边,目标便是每个$x$节点完成匹配. 然后--我菜翻了--神$TM$ if(match[v]==-1||find(v)) 大声告诉我我是不