HDU - 5093 Battle ships

http://acm.hdu.edu.cn/showproblem.php?pid=5093

题意:*代表海洋 o代表浮冰 #代表冰山

现在我们需要尽可能多的在海上放船只,需满足一些条件 (一行 一列只能出现一条船,如果被冰山隔开,可多放置(冰山类似于墙))

思路:我们对于行列的联通块打编号,然后如果海洋的位置我们将它们的编号建图 跑最大匹配即可

#include<bits/stdc++.h>
#define mod 1000000007
#define maxn 100005
using namespace std;
typedef long long ll;
int x[105][105];
int y[105][105];
char mp[105][105];
int vis[3005];
int match[3005];
int tmp;
vector<int> G[3005];
void add(int u,int v){
    G[u].push_back(v);
}
int dfs(int x){
    for(auto u:G[x]){
        if(!vis[u]){
            vis[u]=1;
            if(match[u]==-1||dfs(match[u])){
                match[u]=x;
                return 1;
            }
        } 
    }
    return 0;
}
int solve(){
    int ans=0;
    for(int i=1;i<=tmp-1;i++){
        memset(vis,0,sizeof(vis));
        if(dfs(i))
        ans++;
    }    
    return ans;
}
int main(){
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {    
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(match,-1,sizeof(match));
        memset(mp,0,sizeof(mp));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%s",mp[i]+1);
        }
        int cnt=1;
        for(int i=1;i<=n;i++){
            int fg=0;
            for(int j=1;j<=m;j++){
                if(mp[i][j]=='*'&&fg==0){
                    fg=1;
                    int k=j;
                    while(mp[i][++k]=='*'||mp[i][k]=='o'){
                        if(mp[i][k]=='*')
                        x[i][k]=cnt;
                    }
                    x[i][j]=cnt;
                    j=k-1;
                    cnt++;
                }else {
                    if(mp[i][j]=='#'){
                        fg=0;
                    }
                }
            }
        }
        tmp=cnt;
        cnt=1;
        for(int i=1;i<=m;i++){
            int fg=0;
            for(int j=1;j<=n;j++){
                if(mp[j][i]=='*'&&fg==0){
                fg=1;
                int k=j;
                while(mp[++k][i]=='*'||mp[k][i]=='o'){
                    if(mp[k][i]=='*')
                    y[k][i]=cnt;
                }
                y[j][i]=cnt;
                j=k-1;
                cnt++;
                }else {
                    if(mp[j][i]=='#'){
                        fg=0;
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(x[i][j]&&y[i][j]){
                    add(x[i][j],y[i][j]);
                }
            }
        }
        cout<<solve()<<endl;
        for(int i=1;i<=tmp-1;i++){
            G[i].clear();
        }
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/MengX/p/10746377.html