【TJOI & HEOI 2016】【BZOJ 4554】【JZOJ 4612】 游戏

Description

这里写图片描述
这里写图片描述

Analysis

二分图匹配。
由于本人之前中了网络流的毒,此题便乱搞搞出来了。
首先,对于网络流的知识,可以参考专题“网络流与线性规划”
这题,就是最大点独立集。
但是不是裸的,因为有”#”影响一行情况。
所以,一行或一列中,被”#”隔开的部分视为不同的行或列。

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++) 
using namespace std;
const int N=53,M=5105;
int n,m,st,x[N][N],y[N][N];
int pos[M],bz[M],a[M][M];
bool p[M];
char map[N][N];
void link(int u,int v)
{
    a[u][++a[u][0]]=v;
}
bool match(int v)
{
    if(bz[v]==st) return 0;
    bz[v]=st;
    fo(i,1,a[v][0])
    {
        int u=a[v][i];
        if(!pos[u] || match(pos[u]))
        {
            pos[u]=v;
            return 1;
        }
    }
    return 0;
}
int main()
{
    scanf("%d %d\n",&n,&m);
    fo(i,1,n)
    {
        fo(j,1,m) scanf("%c",&map[i][j]);
        scanf("\n");
    }
    int xx=0,yy=0;
    fo(i,1,n)
    {
        xx++;
        fo(j,1,m)
        {
            if(map[i][j]=='#') xx++;
            if(map[i][j]=='*') x[i][j]=xx;
        }
    }
    fo(j,1,m)
    {
        yy++;
        fo(i,1,n)
        {
            if(map[i][j]=='#') yy++;
            if(map[i][j]=='*') y[i][j]=yy;
        }
    }
    int mx=0;
    fo(i,1,n)
        fo(j,1,m)
            if(map[i][j]=='*')
            {
                link(x[i][j],xx+y[i][j]);
                p[x[i][j]]=p[xx+y[i][j]]=1;
                mx=max(mx,xx+y[i][j]);
            }
    int tot=0,t=0;
    fo(i,1,mx)
        if(p[i]) tot++;
    for(st=1;st<=mx;st++)
        if(match(st)) t++;
    printf("%d",t);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值