1. 程式人生 > >【bzoj 4554】【Tjoi2016&Heoi2016】【NOIP2016模擬7.12】遊戲

【bzoj 4554】【Tjoi2016&Heoi2016】【NOIP2016模擬7.12】遊戲

Go AI %d amp noip 現在 匹配 .net space

題目

技術分享圖片

分析

當沒有石頭的時候,就用二分圖匹配來做。
但現在加入了石頭,
所以,求出每行和每列聯通快的個數,如果有一塊平地,包括在某個行聯通塊以及某個列聯通塊中,連邊。

//無聊打了網絡流,匈牙利也可以
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=54;
using namespace std;
int n,m,a[N][N],ans,tot,f[N*N+6][N*N+6],id,v[N*N+6],t;
int b[N][N];
int aug(int x,int y)
{
    if(x==n*m+n) return y;
    v[x]=id;
    for(int i=0;i<=n*m+n;i++)
    {
        if(f[x][i] && v[i]<id)
        {
            int o=aug(i,min(y,f[x][i]));
            if(o)
            {
                f[x][i]-=o;
                f[i][x]+=o;
                return o;
            }
        }
    }
    return 0;
}                           
int main()
{
    scanf("%d%d",&n,&m);
    tot=0;
    for(int i=1;i<=n;i++)
    {
        tot++;
        for(int j=1;j<=m;j++)
        {
            char c;
            c=getchar();
            while(c!='*' && c!='x' && c!='#') c=getchar();
            if(c=='*') a[i][j]=1;
            else
                if(c=='x') a[i][j]=2;
                    else
                        a[i][j]=3;
            if(a[i][j]==3 && a[i][j-1]!=3) tot++;
            else
            {
                f[0][tot]=1;
                b[i][j]=tot;
            }
        }
    }
    for(int i=1;i<=m;i++)
    {
        tot++;
        for(int j=1;j<=n;j++)
        {
            if(a[j][i]==3) tot++;
            else
            {
                if(a[j][i]!=2) f[b[j][i]][tot]=1;
                f[tot][n*m+n]=1;
            }
        }
    }
    t=1;
    while(t)
    {
        id++;
        t=aug(0,maxlongint);
        ans+=t;     
    }
    printf("%d",ans);
}

【bzoj 4554】【Tjoi2016&Heoi2016】【NOIP2016模擬7.12】遊戲