码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5093 Battle ships (二分图)

时间:2015-05-04 10:11:04      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你一个m*n(1<=m,n<=50)的图,其中 ‘#’代表冰山, ‘*’代表海洋, ‘o’代表浮冰。。然后让你尽可能放置最多的船,但是要满足一下规矩:

  1. 船不能放在冰山上;
  2. 船不能放到浮冰上
  3. 两艘船之间除非中间有冰山,否则不能在同一列或同一行。

分析:红果果的二分最大匹配。。。。图也很容易构造。。。把每一行被冰山分隔开来的海洋格子连通块(至少一个格子)作为X点,同样的每一列被冰山分隔开来的海洋格子连通块作为Y点,X点与Y点有边相连当且仅当这两个连通块共用一个海洋格子。然后跑二分最大匹配。。。2500个点,妥妥的。

以好像是官方题解,但过不了,把next数组改成nextt能过c++的,过不不了g++。

#include<stdlib.h>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstdio>
using namespace std;
#define N 205
#define M 50005
int ev[M],nextt[M];
int head[M];
int cnt;
bool vis[M];
int pre[M];
char s[N][N];
int x[N][N],y[N][N];
int pn[2];
void addedge(int u,int v){
    ev[cnt]=v;
    nextt[cnt]=head[u];
    head[u]=cnt++;
    return;
}
int find(int x){
    for(int i=head[x];~i;i=nextt[i]){
        int v=ev[i];
        if(!vis[v]){
            vis[v]=1;
            if(pre[v]==-1||find(pre[v]))
            {
                pre[v]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        memset(head,-1,sizeof(head));
        cnt=0;
        memset(pre,-1,sizeof(pre));
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        scanf("%d%d",&n,&m);
        for(int  i=0;i<n;i++)
            scanf("%s",s[i]);
        int num=0;
        for(int i=0;i<n;i++)
        {
            bool flag=0;
            for(int j=0;j<m;j++){
                if(s[i][j]=='*'){
                    if(flag==0)
                        num++;
                    x[i][j]=num;
                    flag=1;
                }
                else if(s[i][j]=='#')
                    flag=0;
            }
        }
        pn[0]=num;
        num=0;
        for(int  i=0;i<m;i++)
        {
            bool flag=0;
            for(int j=0;j<n;j++){
                if(s[j][i]=='*'){
                    if(flag==0) num++;
                    y[j][i]=num;
                    flag=1;
                }
                else if(s[j][i]=='#')
                    flag=0;
            }
        }
        pn[1]=num;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
        {
            int u = x[i][j],v=y[i][j];
            if(u&&v) addedge(u,v);
        }
        int ans=0;
        for(int i=1;i<=pn[0];++i)
        {
            memset(vis,0,sizeof(vis));
            ans+=find(i);
        }
        printf("%d\n",ans);
    }
    return 0;
}


HDU5093 Battle ships (二分图)

标签:

原文地址:http://blog.csdn.net/a197p/article/details/45462015

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!