博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「Luogu3355」 骑士共存问题
阅读量:6416 次
发布时间:2019-06-23

本文共 1614 字,大约阅读时间需要 5 分钟。

「Luogu3355」 骑士共存问题

Solution

二分图最大点独立集问题

首先对棋盘黑白染色

从所有无障碍的黑点向能攻击到的无障碍的白点连边

按照二分图最大点独立集=二分图最大匹配,跑二分图匹配即可

Code

#include 
#include
#include
#include
#include
#include
#define maxn 205#define maxm 40005using namespace std;typedef long long ll;template
void read(T &t){ t=0;char c=getchar();int f=0; while(!isdigit(c)){f|=c=='-';c=getchar();} while(isdigit(c)){t=t*10+c-'0';c=getchar();} if(f)t=-t;}int n,m;int ocr[maxm];int ans;struct edge{ int u,v,nxt;}g[maxm*4];int head[maxm],ecnt;void eADD(int u,int v){ g[++ecnt].u=u; g[ecnt].v=v; g[ecnt].nxt=head[u]; head[u]=ecnt;}inline int trans(int x,int y){ return (x-1)*n+y;}int result[maxm],use[maxm],sign;bool Hungary(int u){ for(register int i=head[u];i;i=g[i].nxt) { int v=g[i].v; if(use[v]==sign) continue; use[v]=sign; if(!result[v] || Hungary(result[v])) { result[v]=u; return true; } } return false;}void Calc(){ for(register int i=1;i<=n;++i) for(register int j=1;j<=n;++j) if(!ocr[trans(i,j)] && (i+j)&1) { sign=trans(i,j); ans+=Hungary(trans(i,j)); }}const int dx[8]={-2,-2,-1,-1,1,1,2,2},dy[8]={-1,1,-2,2,-2,2,-1,1};int main(){ read(n),read(m); for(register int i=1;i<=m;++i) { int x,y; read(x),read(y); ocr[trans(x,y)]=1; } for(register int i=1;i<=n;++i) for(register int j=1;j<=n;++j) if(!ocr[trans(i,j)] && (i+j)&1) for(register int k=0;k<8;++k) { int X=i+dx[k],Y=j+dy[k]; if(X<1 || X>n || Y<1 || Y>n || ocr[trans(X,Y)]) continue; eADD(trans(i,j),trans(X,Y)); } Calc(); printf("%d",n*n-m-ans); return 0;}

转载于:https://www.cnblogs.com/lizbaka/p/10505667.html

你可能感兴趣的文章
MySQL的变量查看和设置
查看>>
android onNewIntent
查看>>
XML特殊符号
查看>>
kaptcha可配置项
查看>>
JavaMail邮箱验证用户注册
查看>>
系统时间——ntpd
查看>>
反射实现AOP动态代理模式(Spring AOP实现原理)
查看>>
Http协议与缓存
查看>>
监测超过特定内存阀值进程并结束
查看>>
Linux Centos 查询信息
查看>>
android adb命令
查看>>
python “双”稀疏矩阵转换为最小联通量“单”矩阵
查看>>
揭秘天猫双11背后:20万商家600万张海报,背后只有一个鹿班
查看>>
重置mysq root密码脚本
查看>>
我的友情链接
查看>>
MHA配置参数
查看>>
深入理解Lock
查看>>
vim的块选择
查看>>
HTML --块
查看>>
在DLL中获取主进程窗口句柄
查看>>