[bzoj-4808]马 题解

来源:互联网 发布:vbscript和vb 编辑:程序博客网 时间:2024/06/05 02:34

题目传送门
题意解析:题目给了一张图,上面有的地方不能放马(中国象棋里的),问最多能放几只马。


……..跟bzoj3175几乎一模一样,包括数据范围,所以详情请见bzoj3175
代码,好像也一样:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define rep(i,a,n) for (int i=a;i<=n;i++)#define per(i,a,n) for (int i=a;i>=n;i--)#define Clear(a,x) memset(a,x,sizeof(a))#define ll long long#define INF 2000000000#define eps 1e-8using namespace std;int read(){    int x=0,f=1;    char ch=getchar();    while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}const int maxn=205,maxm=maxn*maxn;const int dx[8]={-1,-2,-2,-1,1,2,2,1},dy[8]={-2,-1,1,2,2,1,-1,-2};int n,m,len,ans,sum;int map[maxn][maxn],match[maxm];int vet[maxm<<4],Next[maxm<<4],head[maxm];bool flag[maxm];void add(int u,int v){    vet[++len]=v;    Next[len]=head[u];    head[u]=len;}int calc(int x,int y){    return (x-1)*m+y;}bool dfs(int u){    for (int e=head[u];e;e=Next[e]){        int v=vet[e];        if (flag[v]) continue;        flag[v]=1;        int t=match[v];        match[v]=u;        if (t==-1||dfs(t))            return true;        match[v]=t;    }    return false;}int main(){    n=read(),m=read();    rep(i,1,n)        rep(j,1,m) map[i][j]=read(),sum+=(map[i][j]==0);    rep(i,1,n)        rep(j,1,m)            rep(k,0,7){                if (map[i][j]==1) break;                int xx=dx[k]+i,yy=dy[k]+j;                if (xx<1||xx>n||yy<1||yy>m||map[xx][yy]==1) continue;                int u=calc(i,j),v=calc(xx,yy);                add(u,v);            }    Clear(match,-1);    rep(i,1,n)        rep(j,1,m) if (map[i][j]==0){            Clear(flag,0);            flag[calc(i,j)]=1;            ans+=dfs(calc(i,j));        }    printf("%d\n",sum-ans/2);    return 0;}
原创粉丝点击