HDU 5093 二分最大匹配

Battle ships

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 394    Accepted Submission(s): 178

Problem Description

Dear contestant, now you are an excellent navy commander, who is responsible of a tough mission currently.

Your fleet unfortunately encountered an enemy fleet near the South Pole where the geographical conditions are negative for both sides. The floating ice and iceberg blocks battleships move which leads to this unexpected engagement highly dangerous, unpredictable and incontrollable.

But, fortunately, as an experienced navy commander, you are able to take opportunity to embattle the ships to maximize the utility of cannons on the battleships before the engagement.

The target is, arrange as many battleships as you can in the map. However, there are three rules so that you cannot do that arbitrary:

A battleship cannot lay on floating ice
A battleship cannot be placed on an iceberg

Two battleships cannot be arranged in the same row or column, unless one or more icebergs are in the middle of them.

Input

There is only one integer T (0<T<12) at the beginning line, which means following T test cases.

For each test case, two integers m and n (1 <= m, n <= 50) are at the first line, represents the number of rows and columns of the battlefield map respectively. Following m lines contains n characters iteratively, each character belongs to one of ‘#’, ‘*’, ‘o’, that symbolize iceberg, ordinary sea and floating ice.

Output

For each case, output just one line, contains a single integer which represents the maximal possible number of battleships can be arranged.

Sample Input

2

4 4

*ooo

o###

**#*

ooo*

4 4

#***

*#**

**#*

ooo#

Sample Output

3

5

题目意思:

给一个n*m的图,‘*’表示海洋,‘O’表示浮冰,‘#’表示冰山。一艘军舰只能停在海洋上,两艘军舰不能在同一行或同一列,或者在同一行或同一列当且仅当它们之间有冰山使它们隔开。

思路:

白书上有建图模型,挺好的一道二分匹配的题目。想想,设一艘军舰在点map[i][j]处,点i和点j连一条边,若两艘军舰不在同一行,那么不就是和行结点只连一条边么,放置最多的军舰不就相当于最大匹配么。行列缩点建边,求最大匹配即为答案。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8
 9 #define N 55
10
11 int max(int x,int y){return x>y?x:y;}
12 int min(int x,int y){return x<y?x:y;}
13 int abs(int x,int y){return x<0?-x:x;}
14
15 char map[N][N];
16 int n, m;
17 bool visited[2505];
18 int from[2505];
19 int a[N][N];     //行缩点
20 int b[N][N];     //列缩点
21 int cnt_a, cnt_b;
22 vector<int>ve[N*N];
23
24 int march(int u){
25     int i, v;
26     for(i=0;i<ve[u].size();i++){
27         v=ve[u][i];
28         if(!visited[v]){
29             visited[v]=true;
30             if(from[v]==-1||march(from[v])){
31                 from[v]=u;
32                 return 1;
33             }
34         }
35     }
36     return 0;
37 }
38
39 main()
40 {
41     int t, i, j, k;
42     cin>>t;
43     while(t--){
44         scanf("%d %d",&n,&m);
45         memset(map,‘\0‘,sizeof(map));
46         memset(a,0,sizeof(a));
47         memset(b,0,sizeof(b));
48         for(i=1;i<=n;i++) scanf("%s",map[i]+1);
49         cnt_a=1;
50         for(i=1;i<=n;i++){              //对行缩点
51             for(j=1;j<=m;j++){
52                 if(map[i][j]!=‘#‘){
53                     if(map[i][j-1]==‘#‘){
54                         cnt_a++;
55                         a[i][j]=cnt_a;
56                     }
57                     else a[i][j]=cnt_a;
58                 }
59             }
60             cnt_a++;
61         }
62         for(i=0;i<=cnt_a;i++) ve[i].clear();
63         cnt_b=1;
64         for(j=1;j<=m;j++){            //对列缩点
65             for(i=1;i<=n;i++){
66                 if(map[i][j]!=‘#‘){
67                     if(map[i-1][j]==‘#‘){
68                         cnt_b++;
69                         b[i][j]=cnt_b;
70                     }
71                     else b[i][j]=cnt_b;
72                 }
73             }
74             cnt_b++;
75         }
76         for(i=1;i<=n;i++){              //缩点后的行列建边
77             for(j=1;j<=m;j++){
78                 if(map[i][j]==‘*‘){
79                     ve[a[i][j]].push_back(b[i][j]);
80                 }
81             }
82         }
83
84         memset(from,-1,sizeof(from));
85         int ans=0;
86         for(i=1;i<=cnt_a;i++){            //匈牙利求最大匹配
87             memset(visited,false,sizeof(visited));
88             if(march(i)) ans++;
89         }
90         printf("%d\n",ans);
91     }
92 }
时间: 2024-08-05 00:17:33

HDU 5093 二分最大匹配的相关文章

HDU 5090 二分最大匹配

Game with Pearls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 646    Accepted Submission(s): 284 Problem Description Tom and Jerry are playing a game with tubes and pearls. The rule of the ga

Battle ships HDU - 5093二分匹配

Battle shipsHDU - 5093 题目大意:n*m的地图,*代表海洋,#代表冰山,o代表浮冰,海洋上可以放置船舰,但是每一行每一列只能有一个船舰(类似象棋的車),除非同行或者同列的船舰中间有冰山挡着,问最多能放多少个船舰? 之前做过一个放置炮的,那时数据小直接暴力加搜索就A了,然而这题暴力搜索的话,直接了当的TLE,没办法只好去学新东西了.二分图这个概念只有在之前的题目中做过匈牙利的板子题,可是具体概念和思路并不了解,这题也正好提醒了我去深入了解.但最近需要做的事情较大,一直想整理的

hdu 5093 二分匹配

/* 题意:给你一些冰岛.公共海域和浮冰,冰岛可以隔开两个公共海域,浮冰无影响 求选尽可能多的选一些公共海域点每行每列仅能选一个. 限制条件:冰山可以隔开这个限制条件.即*#*可以选两个 预处理: ***** **#*# ***** 可以按行转化 ***** **#oo ooo*# ***** 按列转化 ***o**o **ooooo oooo*oo **o**o* 因为每行每列顶多可以增加50 所以总共最多2500*2500的矩阵 然后直接二分匹配即可 */ #include<stdio.h>

HDU 1498 50 years, 50 colors(二分最大匹配之最小点覆盖)

题目地址:HDU 1498 晕啊...三个人同时做的这个题,结果全都理解错意思了..而且每个人理解错的地方还都不一样..但是样例还都能过,...简直炫酷... 题意:n*n的矩阵放置不同的颜色(不同的数字代表不同的颜色),你有k次选择,每一次只能选择某一行或某一列,可以消除该行(列)的所有颜色,问有哪几种颜色,无论怎样经过k次选择后依然无法完全抹去. 这个题的思路就是分别求出每种颜色的最少操作次数.然后只要大于k次的就是不符合要求的.然后输出就行了. #include <iostream> #

Hdu 2389 二分匹配

题目链接 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Others)Total Submission(s): 2644    Accepted Submission(s): 823 Problem Description You’re giving a party in the garden of your villa by the sea. T

HDU 5093

http://acm.hdu.edu.cn/showproblem.php?pid=5093 二分图最大匹配的经典建图模型,行列分别缩点(连起来的'*' & 'o'),交集有'*'就连边 #include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; struct node

hdu 2255 二分图带权匹配 模板题

模板+注解在 http://blog.csdn.net/u011026968/article/details/38276945 hdu 2255 代码: //KM×î´ó×îСƥÅä #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define INF 0x0fffffff const int MAXN

POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))

题目链接: http://poj.org/problem?id=3041 Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently

HDU 1528 (二分图最大匹配 + 最小覆盖, 14.07.17)

Problem Description Adam and Eve play a card game using a regular deck of 52 cards. The rules are simple. The players sit on opposite sides of a table, facing each other. Each player gets k cards from the deck and, after looking at them, places the c