hdu 5093 Battle ships 二分匹配

来源:互联网 发布:飞龙淘宝小号浮云网 编辑:程序博客网 时间:2024/05/17 23:19

题意:在n×m的方格中,‘#’代表iceberg,'*'代表ocean,‘o’代表floating ice。战舰只能放在ocean上,在同一行或者同一列不能放两

个战舰除非它们中间有iceberg,求最多能放多少战舰。

思路:二分匹配。每行中连续为'*'的作为X集合中一个点,同样,将每列中连续为'*'的点作为Y集合中的一个点。对原图中每个'*',将其对应的X集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配。详见代码:

/*********************************************************  file name: hdu5093.cpp  author : kereo  create time:  2015年02月02日 星期一 15时11分33秒*********************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int sigma_size=26;const int N=50+50;const int MAXN=2500+50;const int inf=0x3fffffff;const double eps=1e-8;const int mod=100000000+7;#define L(x) (x<<1)#define R(x) (x<<1|1)#define PII pair<int, int>#define mk(x,y) make_pair((x),(y))int n,m,edge_cnt;char mp[N][N];int head[MAXN],vis[MAXN],link[MAXN],x[N][N],y[N][N];struct Edge{    int v,next;}edge[MAXN];void init(){    edge_cnt=0;    memset(link,-1,sizeof(link));    memset(head,-1,sizeof(head));}void addedge(int u,int v){    edge[edge_cnt].v=v;    edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;}bool dfs(int u){    for(int i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].v;        if(vis[v])            continue;        vis[v]=1;        if(link[v] == -1 || dfs(link[v])){            link[v]=u;            return true;        }    }    return false;}int main(){    //freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        init();        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++)            scanf("%s",mp[i]);        int cnt1=0,cnt2=0;        for(int i=0;i<n;i++){            int flag=1;            for(int j=0;j<m;){                if(mp[i][j] == '*'){                    if(flag)                        ++cnt1;                    flag=0;                     while(j<m && mp[i][j] == '*'){                        x[i][j]=cnt1;                        j++;                    }                }                else if(mp[i][j] == 'o'){                    while(j<m && mp[i][j] == 'o')                        j++;                }                else{                    flag=1;                     while(j<m && mp[i][j] == '#')                        j++;                }            }        }        for(int j=0;j<m;j++){            int flag=1;            for(int i=0;i<n;){                if(mp[i][j] == '*'){                    if(flag)                        ++cnt2;                    flag=0;                     while(i<n && mp[i][j] == '*'){                        y[i][j]=cnt2;                        i++;                    }                }                else if(mp[i][j] == 'o'){                    while(i<n && mp[i][j] == 'o')                        i++;                }                else{                    flag=1;                    while(i<n && mp[i][j] == '#')                        i++;                }            }        }        for(int i=0;i<n;i++)            for(int j=0;j<m;j++)                if(mp[i][j] == '*')                    addedge(x[i][j],y[i][j]);        int ans=0;        for(int i=1;i<=cnt1;i++){            memset(vis,0,sizeof(vis));            if(dfs(i))                ans++;        }        printf("%d\n",ans);    }return 0;}

0 0
原创粉丝点击