传送门

模型

二分图最大独立集,转化为二分图最大匹配,从而用最大流解决。

实现

首先把棋盘黑白染色,使相邻格子颜色不同。

把所有可用的黑色格子看做二分图X集合中顶点,可用的白色格子看做Y集合顶点。

建立附加源S汇T,从S向X集合中每个顶点连接一条容量为1的有向边,从Y集合中每个顶点向T连接一条容量为1的有向边。

从每个可用的黑色格子向骑士一步能攻击到的可用的白色格子连接一条容量为无穷大的有向边。

求出网络最大流,要求的结果就是可用格子的数量减去最大流量。

分析

用网络流的方法解决棋盘上的问题,一般都要对棋盘黑白染色,使之成为一个二分图。放尽可能多的不能互相攻击的骑士,就是一个二分图最大独立集问题。有关二分图最大独立集问题,更多讨论见《最小割模型在信息学竞赛中的应用》作者胡伯涛。

该题规模比较大,需要用效率较高的网络最大流算法解决。(使用Dinic+当前弧优化)

——代码

 #include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define INF 1e9
#define N 1000001
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, m, cnt, tot, sum, s, t;
int map[][], head[N], to[N], val[N], next[N], dis[N], cur[N];
int dx[] = {-, -, , , , , -, -},
dy[] = {, , , , -, -, -, -}; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline void add2(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
next[cnt] = head[x];
head[x] = cnt++;
} inline void add(int x, int y, int z)
{
add2(x, y, z);
add2(y, x, );
} inline bool bfs()
{
int i, u, v;
std::queue <int> q;
memset(dis, -, sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == -)
{
dis[v] = dis[u] + ;
if(v == t) return ;
q.push(v);
}
}
}
return ;
} inline int dfs(int u, int maxflow)
{
if(u == t) return maxflow;
int v, d, ret = ;
for(int &i = cur[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] == dis[u] + )
{
d = dfs(v, min(val[i], maxflow - ret));
ret += d;
val[i] -= d;
val[i ^ ] += d;
if(ret == maxflow) return ret;
}
}
return ret;
} int main()
{
int i, j, k, x, y;
n = read();
m = read();
s = , t = n * n + ;
memset(head, -, sizeof(head));
for(i = ; i <= m; i++)
{
x = read();
y = read();
map[x][y] = -;
}
for(i = ; i <= n; i++)
for(j = ; j <= n; j++)
if(!map[i][j])
{
map[i][j] = ++tot;
if((i + j) & ) add(s, tot, );
else add(tot, t, );
}
for(i = ; i <= n; i++)
for(j = ; j <= n; j++)
if(map[i][j] ^ - && (i + j) & )
for(k = ; k < ; k++)
{
x = i + dx[k];
y = j + dy[k];
if(x >= && x <= n && y >= && y <= n && map[x][y] ^ -) add(map[i][j], map[x][y], INF);
}
while(bfs())
{
for(i = s; i <= t; i++) cur[i] = head[i];
sum += dfs(s, INF);
}
printf("%d\n", tot - sum);
return ;
}

[luoguP3355] 骑士共存问题(二分图最大独立集)的更多相关文章

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

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

  2. 【Codevs1922】骑士共存问题(最小割,二分图最大独立集转最大匹配)

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

  3. 「CODVES 1922 」骑士共存问题(二分图的最大独立集|网络流)&dinic

    首先是题目链接  http://codevs.cn/problem/1922/ 结果发现题目没图(心情复杂 然后去网上扒了一张图 大概就是这样了. 如果把每个点和它可以攻击的点连一条边,那问题就变成了 ...

  4. Cogs 746. [网络流24题] 骑士共存(最大独立集)

    [网络流24题] 骑士共存 ★★☆ 输入文件:knight.in 输出文件:knight.out 简单对比 时间限制:1 s 内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国 ...

  5. COGS746. [网络流24题] 骑士共存

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

  6. 【刷题】LOJ 6226 「网络流 24 题」骑士共存问题

    题目描述 在一个 \(\text{n} \times \text{n}\) 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的 \(\t ...

  7. P3355 骑士共存问题

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

  8. BZOJ3175:[TJOI2013]攻击装置(二分图最大独立集)

    Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2), ...

  9. [网络流24题] 骑士共存(cogs 746)

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

随机推荐

  1. Android(java)学习笔记107:Relativelayout相对布局

    1. Relativelayout相对布局案例: 我们看看案例代码,自己心领神会: <?xml version="1.0" encoding="utf-8" ...

  2. HTML5<section>元素

    HTML5<section>元素用来定义页面文档中的逻辑区域或内容的整合(section,区域),比如章节.页眉.页脚或文档中的其他部分. 根据W3C HTML5文档中:section里面 ...

  3. graphviz 绘制架构图

    架构图: 1.依赖调用关系.(类似文献引用关系, graphviz 自动将每一次调用升一次层级) 2.依赖调用可能是上下层级调用,也可能是同层级引用. 需人工去梳理出这些关系 3. 引用多的用颜色标识 ...

  4. 01_11_SERVLET中使用javabean

    01_11_SERVLET中使用javabean 1. javabean 广义javabean = 普通java类 狭义javabean = 符合 Sun JavaBean标准的类 在Servlet中 ...

  5. cocos2dx lua 打印和保存日志

    在2d游戏中,经常会出现闪退或者报错的问题,通过写文本,将日志文件发送给服务端,让后端人员进行分析. 通过lua打印日志在文本文件中: local file = io.open(cc.FileUtil ...

  6. 一句话懂什么是JS闭包

    无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包.闭包包含在函数创建时作用域中的所有变量,它类似于背包.函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量. 我将永远记住 ...

  7. B. Anatoly and Cockroaches

    B. Anatoly and Cockroaches time limit per test 1 second memory limit per test 256 megabytes input st ...

  8. 【启发式搜索】Codechef March Cook-Off 2018. Maximum Tree Path

    有点像计蒜之道里的 京东的物流路径 题目描述 给定一棵 N 个节点的树,每个节点有一个正整数权值.记节点 i 的权值为 Ai.考虑节点 u 和 v 之间的一条简单路径,记 dist(u, v) 为其长 ...

  9. ubuntu16.04安装mongodb,创建数据库管理员,上传文件到服务器上

    1.导入软件源得公钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 2.为mongodb创建软件 ...

  10. Powershell 备忘

    如何修改环境变量 [environment]::SetEnvironmentvariable(“path”,"xxx","user") [environment ...