CH6901 骑士放置

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH6901 骑士放置相关的知识,希望对你有一定的参考价值。

描述

给定一个 N*M 的棋盘,有一些格子禁止放棋子。问棋盘上最多能放多少个不能互相攻击的骑士(国际象棋的“骑士”,类似于中国象棋的“马”,按照“日”字攻击,但没有中国象棋“别马腿”的规则)。N, M<=100。

输入格式

第一行为n,m,t(表示有t个禁止的格子)
第二行到t+1行为x,y,分别表示禁止格子所在的位置,x为第x行,y为第y列,行列编号从1开始。 

输出格式

一个整数,表示最多能放多少个骑士。

样例输入

2 3 0

样例输出

4

题解

跳“日”字时行列号之和的该变量为奇数,所以这是二分图。

那么求的就是二分图最大独立集,等于点数减去最大匹配数。时间复杂度\(O(n^2m^2)\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read()
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;

template<class T>il T read(rg T&x) return x=read<T>();
typedef long long ll;
using namespace std;

co int N=101;
int n,m,t,ans,fx[N][N],fy[N][N];
bool a[N][N],v[N][N];
co int dx[8]=-2,-2,-1,-1,1,1,2,2;
co int dy[8]=-1,1,-2,2,-2,2,-1,1;
bool dfs(int x,int y)
    for(int i=0;i<8;++i)
        int nx=x+dx[i],ny=y+dy[i];
        if(nx<1||nx>n||ny<1||ny>m||a[nx][ny]||v[nx][ny]) continue;
        v[nx][ny]=1;
        if(!fx[nx][ny]||dfs(fx[nx][ny],fy[nx][ny]))
            fx[nx][ny]=x,fy[nx][ny]=y;
            return 1;
        
    
    return 0;

int main()
    read(n),read(m),read(t);
    for(int i=1;i<=t;++i) a[read<int>()][read<int>()]=1;
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
        if(i+j&1||a[i][j]) continue;
        memset(v,0,sizeof v);
        ans+=dfs(i,j);
    
    printf("%d\n",n*m-t-ans);
    return 0;

以上是关于CH6901 骑士放置的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 378. 骑士放置

陷入无限循环(骑士之旅问题)

带回溯的骑士​​之旅

在选项卡式应用程序中的何处放置位置代码?

Android使用片段在viewpager中的页面滚动上放置动画

骑士共存问题