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{
    int s,t,nxt ;
}e[2500005] ;
int k,m,n,head[5005],cnt,match[5005],vis[5005] ;
int find(int s)
{
    for(int i=head[s] ;i!=-1 ;i=e[i].nxt)
    {
        int tt=e[i].t ;
        if(!vis[tt])
        {
            vis[tt]=1 ;
            if(match[tt]==-1 || find(match[tt]))
            {
                match[tt]=s ;
                return 1 ;
            }
        }
    }
    return 0 ;
}
int cr,cc;
int max_match()
{
    int ans=0 ;
    memset(match,-1,sizeof(match)) ;
    for(int i=1 ;i<cr ;i++)
    {
        memset(vis,0,sizeof(vis)) ;
        ans+=find(i);
    }
    return ans;
}
void add(int s,int t) {e[cnt].s=s ;e[cnt].t=t ;e[cnt].nxt=head[s] ;head[s]=cnt++ ;}
char M[55][55];
int mpr[55][55],mpc[55][55];
void read_graph()
{
    memset(head,-1,sizeof(head)) ;
    cnt=0 ;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(M[i][j]==‘*‘)
                add(mpr[i][j],mpc[i][j]);
}
int main(){
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%s",M[i]);
        }
        memset(mpr,-1,sizeof(mpr));
        memset(mpc,-1,sizeof(mpc));
        cr=cc=1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(M[i][j]==‘*‘ && mpr[i][j] == -1){
                    for(int k=j;(M[i][k]==‘*‘ || M[i][k]==‘o‘) && k<n;k++)
                        mpr[i][k]=cr;
                    cr++;
                }
                if(M[j][i]==‘*‘ && mpc[j][i]==-1){
                    for(int k=j;(M[k][i]==‘*‘ || M[k][i]==‘o‘) && k<n;k++)
                        mpc[k][i]=cc;
                    cc++;
                }
            }
        }
        read_graph();
        printf("%d\n",max_match());
    }
    return 0;
}

时间: 2024-10-05 04:05:20

HDU 5093的相关文章

hdu 5093 Battle ships 最大二分匹配

Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 589    Accepted Submission(s): 233 Problem Description Dear contestant, now you are an excellent navy commander, who is responsible

hdu 5093 Battle ships 二分图匹配

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5093 一开始就往贪心的方向想了结果wa全场 这种矩阵形式的图一般要联想到行和列构成了二分图 然后实质就是求一个最大匹配 中间的冰山实际上就是把一行或一列切成多个顶点而已 所以一开始预处理一下 然后就可以套用模板 #include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #i

Battle ships HDU - 5093二分匹配

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

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 o

hdu 5093 Battle ships

二分图匹配 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #define maxn 60 6 #define maxd 1500 7 using namespace std; 8 int v[maxd][maxd],vist[maxd],math[maxd]; 9 10 int col[maxn][maxn],row[maxn][maxn]; 1

hdu 5093 Battle ships二分图

二分图最大匹配问题 遇到冰山就把行列拆成两个部分.每个部分x也好,y也好只能匹配一次 图画得比较草,将就着看 横着扫一遍,竖着扫一遍,得到编号 一个位置就对应一个(xi,yi)就是X集到Y集的一条边, 由题意,每个点只能被选择一次.所以最大匹配的边数就是答案了. 算法过程 通常都是先贪心求一个匹配,然后开始增广. 寻找增广路的过程: 一个没有和任意边匹配的点叫做未盖点,从左集X中一个未盖点u出发寻找增广路. 从u出发,选一个非匹配边到达Y集中的v,如果v没匹配,那么就找到一条增广路(只要把之前走

hdu 5093 二分匹配

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

hdu 5093 Battle ships 二分匹配

题意:在n×m的方格中,'#'代表iceberg,'*'代表ocean,'o'代表floating ice.战舰只能放在ocean上,在同一行或者同一列不能放两 个战舰除非它们中间有iceberg,求最多能放多少战舰. 思路:二分匹配.每行中连续为'*'的作为X集合中一个点,同样,将每列中连续为'*'的点作为Y集合中的一个点.对原图中每个'*',将其对应的X集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配.详见代码: /*********************************

HDU 5093 Battle ships(二分图匹配)

该题是一道经典的二分图匹配题目 .  同一列(行)上不能放两个船除非有冰山隔着.对于这种二维平面图,我们很容易想到将行和列分成两个集合,进行二分图匹配,当一个行坐标匹配到一个列坐标时,该格子可以放置船.那么为了使任意两个船都不在同一行或者同一列,除非有冰山,我们可以将每一行中一块连续的只能放置一个船的区域都设成一个编号,同样的按照列也这样处理,这样就相当于将行和列缩点了,接下来用最大流模板套一套就可以了 . 处理二分图还有一种更好的算法,叫匈牙利算法,紫书上没有,先用最大流算法解决吧 . 紫书十