题目描述

在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘上某些方格设置了障碍,骑士不得进入

  

对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击

输入输出格式

输入格式:

第一行有 2 个正整数n 和 m (1<=n<=200, 0<=m<n2),分别表示棋盘的大小和障碍数。接下来的 m 行给出障碍的位置。每行 2 个正整数,表示障碍的方格坐标。

输出格式:

将计算出的共存骑士数输出

输入输出样例

输入样例#1: 复制

3 2
1 1
3 3
输出样例#1: 复制

5 
最大流与最小割之间的转换
最多放多少骑士==最少拿走多少
观察图片不难发现:黄色的不能攻击黄色的,红色同理
那么不难想到二分图匹配
这样就转化成了二分图最小定点覆盖
而二分图最小顶点覆盖==二分图最大匹配。证明可以看[这里](http://www.cnblogs.com/jianglangcaijin/p/6035945.html)
从S向红色连边(权重为1),从红色向能攻击到的黄色连边(权重为INF),从黄色向T连边(权重为1)
 
// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<queue>
#define AddEdge(x,y,z) add_edge(x,y,z),add_edge(y,x,0);
using namespace std;
const int MAXN=,INF=1e8+;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=nc();}
while(c>=''&&c<=''){x=x*+c-'';c=nc();}
return x*f;
}
int N,M,S,T;
struct node
{
int u,v,flow,nxt;
}edge[MAXN*];
int head[MAXN],cur[MAXN],num=;
inline void add_edge(int x,int y,int z)
{
edge[num].u=x;
edge[num].v=y;
edge[num].flow=z;
edge[num].nxt=head[x];
head[x]=num++;
}
int deep[MAXN];
inline bool BFS()
{
memset(deep,,sizeof(deep));
deep[S]=;
queue<int>q;
q.push(S);
while(q.size()!=)
{
int p=q.front();
q.pop();
for(int i=head[p];i!=-;i=edge[i].nxt)
if(!deep[edge[i].v]&&edge[i].flow)
{
deep[edge[i].v]=deep[p]+;q.push(edge[i].v);
if(edge[i].v==T) return ;
}
}
return deep[T];
}
int DFS(int now,int nowflow)
{
if(now==T||nowflow<=) return nowflow;
int totflow=;
for(int &i=cur[now];i!=-;i=edge[i].nxt)
{
if(deep[edge[i].v]==deep[now]+&&edge[i].flow)
{
int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow));
edge[i].flow-=canflow;edge[i^].flow+=canflow;
totflow+=canflow;
nowflow-=canflow;
if(nowflow<=) break;
}
}
return totflow;
}
int Dinic()
{
int ans=;
while(BFS())
{
memcpy(cur,head,sizeof(head));
ans+=DFS(S,INF);
}
return ans;
}
int a[][],c[][];
int xx[]={,-,-,-,-,+,+,+,+};
int yy[]={,-,-,+,+,+,+,-,-};
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
memset(head,-,sizeof(head));
N=read();M=read();S=;T=N*N+;
for(int i=;i<=M;i++)
{
int x=read(),y=read();
c[x][y]=;
}
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
a[i][j]=(i-)*N+j;
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
{
if(c[i][j]) continue;
if((i+j)%)
{
AddEdge(S,a[i][j],);
for(int k=;k<=;k++)
{
int wx=i+xx[k],wy=j+yy[k];
if(wx>=&&wx<=N&&wy>=&&wy<=N)
AddEdge(a[i][j],a[wx][wy],INF);
}
}
else AddEdge(a[i][j],T,);
}
printf("%d",N*N-M-Dinic()); return ;
}
 

洛谷P3355 骑士共存问题的更多相关文章

  1. 2018.08.02 洛谷P3355 骑士共存问题(最小割)

    传送门 这题让我联想到一道叫做方格取数问题的题,如果想使摆的更多,就要使不能摆的更少,因此根据骑士的限制条件建图,求出至少有多少骑士不能摆,减一减就行了. 代码: #include<bits/s ...

  2. 洛谷 [P3355] 骑士共存问题

    二分图求最大独立点集 本问题在二分图中已处理过,此处用dinic写了一遍 #include <iostream> #include <cstdio> #include < ...

  3. 洛谷P3355 骑士共存问题(最小割)

    传送门 de了两个小时的bug愣是没发现错在哪里……没办法只好重打了一遍竟然1A……我有点想从这里跳下去了…… 和方格取数问题差不多,把格子按行数和列数之和的奇偶性分为黑的和白的,可以发现某种颜色一定 ...

  4. 洛谷 P3355 骑士共存问题【最小割】

    同方格取数问题:https://www.cnblogs.com/lokiii/p/8430720.html 记得把障碍点去掉,不连边也不计入sum #include<iostream> # ...

  5. 洛谷P3355 骑士共存问题 二分图_网络流

    Code: #include<cstdio> #include<cstring> #include<queue> #include<vector> #i ...

  6. 洛谷.3355.骑士共存问题(最小割ISAP)

    题目链接 一个很暴力的想法:每个点拆点,向不能同时存在的连边 但是这样边太多了,而且会有很多重复.我不会说我还写了还没过样例 我们实际就是在做一个最大匹配.考虑原图,同在黄/红格里的骑士是互不攻击的, ...

  7. P3355 骑士共存问题

    P3355 骑士共存问题 题目描述 在一个 n*n (n <= 200)个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n ...

  8. P3355 骑士共存问题 二分建图 + 当前弧优化dinic

    P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后di ...

  9. P3355 骑士共存问题 网络流

    骑士共存 题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最 ...

随机推荐

  1. 【BZOJ 1293】[SCOI2009]生日礼物

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然的滑动窗口题. (尺取法 如果l..i这一段已经有k种珍珠了. 那么就尝试把l++; (即把l这个影响尝试去掉一下 如果不足k种 ...

  2. Linux学习总结(14)——Linux权限控制

    linux中,权限的学习是必不可少的,不论是作为一名运维工程师或者是单一的管理者,学习好linux中的权限控制,你就可以保护好自己的隐私同时规划好你所管理的一切. 权限的学习是很多的,不要认为自己已经 ...

  3. 一个leetcode解题报告类目,代码很简洁

    http://bookshadow.com/leetcode/ 里面的代码很简洁.可以看.

  4. hadoop-07-ntp服务检查

    hadoop-07-ntp服务检查 cd /etc/more /etc/ntp.conf里面进行了server的配置 service ntpd status / stop/ start 安装ntpd ...

  5. [MST] Store Store in Local Storage

    For an optimal user and developer experience, storing state in local storage is often a must. In thi ...

  6. 好记性不如烂笔头86-spring3学习(7)-ApplicationContext中bean的生命周期

    假设使用ApplicationContext来生成.管理Bean, 一个Bean从建立到销毁,会历经几个运行阶段. 我个人理解一般的bean的生命周期主要包含:建立,初始化,使用阶段,销毁四个核心阶段 ...

  7. Classes and functions

    As another example of a user-defined type, we’ll define a class called Time that records the time of ...

  8. CUDA笔记13

    在新的环境上用CUTIL的时候,出现了问题.无法解析的外部符号 __imp_cutCheckCmdLineFlag 问题描述: kernel.cu.obj : error LNK2019: 无法解析的 ...

  9. 学golang之前都需要哪些前置知识?

    我学golang,感觉前面基础语法部分都很快能学会,但是到了goroutine,channel等后面的部分就看不懂了,是不是我学这个之前还得学习其他什么知识啊?(我有C语言基础,对于C语言里面的指针, ...

  10. Perceptron Learning Algorithm(python实现)

    一.概论 对于给定的n维(两种类型)数据(训练集),找出一个n-1维的面,能够"尽可能"地按照数据类型分开.通过这个面,我们可以通过这个面对测试数据进行预测. 例如对于二维数据,要 ...