Description

一个  的网格图,一些格子有障碍。一条合法路径的定义是从  到 的,一共走  步的路径。
你要把一些格子染黑,使得每一条合法路径上恰好有一个黑点。问合法方案数。

Difficulty

MainAlgorithm

对偶图
DP

Complexity

Solution

首先我们把能从  到的、能到  的点抠出来。其余的点都是自由的,给答案乘  即可。
我们观察这些点,他们构成了一个平面图DAG。
考虑一下染色的意义,即一个极小点割。即这个割集中的每一个点都有用而不可删除。
那么,我们把原图转对偶图,在左下角建立S,在右上角建立T,一个合法的方案即为从S到T的一条路径。

DP统计一下就好。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define Rep(i, x, y) for (int i = x; i <= y; i ++)
#define Dwn(i, x, y) for (int i = x; i >= y; i --)
#define RepE(i, x) for(int i = pos[x]; i; i = g[i].nex)
using namespace std;
typedef long long LL;
const int N = 1005, M = 45, S = 1001, T = 1002, mod = 1000000007;
class OneBlack {
public:char a[N][N]; bool vis[M][M], v1[M][M], v2[M][M], ve[N][N], Ch[M][M];LL f[N], num = 1; int in[N], n, m, pos[N], sz, hd, tl, que[N], c[M][M], col, cl, b[N][N];struct Edge { int y, nex; } g[N * N];void Init(int x, int y) {if (x == y || ve[x][y]) return ;g[++ sz] = (Edge) { y, pos[x] }, pos[x] = sz;in[y] ++, ve[x][y] = 1;}void Find(int x, int y) {if (x > n || y > m || vis[x][y] || c[x][y]) return ;c[x][y] = col;Find(x + 1, y), Find(x, y + 1), Find(x + 1, y + 1);}void Dfs(int x, int y) {if (!x || y > m) col = S;if (x > n || !y) col = T;if (col == S || col == T || vis[x][y] || Ch[x][y]) return ;Ch[x][y] = 1;Dfs(x + 1, y), Dfs(x - 1, y), Dfs(x, y - 1), Dfs(x, y + 1);}int countColorings(vector <string> grid) {n = grid.size();m = grid[0].size();Rep(i, 1, n) {Rep(j, 1, m) a[i][j] = grid[i - 1][j - 1];}v1[1][0] = 1, v2[n + 1][m] = 1;Rep(i, 1, n) {Rep(j, 1, m) if (a[i][j] != '#') {v1[i][j] = v1[i - 1][j] | v1[i][j - 1];vis[i][j] = v1[i][j];}}Dwn(i, n, 1) {Dwn(j, m, 1) if (a[i][j] != '#') {v2[i][j] = v2[i + 1][j] | v2[i][j + 1];vis[i][j] &= v2[i][j];}}Rep(i, 1, n) {Rep(j, 1, m) if (a[i][j] != '#' && !vis[i][j]) (num *= 2) %= mod;}Rep(i, 1, n) {Rep(j, 1, m) {if (!c[i][j] && !vis[i][j]) col = (++ cl), Dfs(i, j), Find(i, j);else if (!c[i][j]) b[i][j] = ++ cl;}}Rep(i, 1, n) c[i][0] = T, c[i][m + 1] = S;Rep(i, 1, m) c[0][i] = S, c[n + 1][i] = T;Rep(i, 1, n) {Rep(j, 1, m) {int x = c[i][j];if (!x) {x = b[i][j];if (c[i + 1][j]) Init(x, c[i + 1][j]);if (c[i][j - 1]) Init(x, c[i][j - 1]);if (!c[i + 1][j] && !c[i][j - 1]) Init(x, max(b[i + 1][j - 1], c[i + 1][j - 1]));} else {if (b[i + 1][j]) Init(x, b[i + 1][j]);if (b[i][j - 1]) Init(x, b[i][j - 1]);if (b[i + 1][j - 1]) Init(x, b[i + 1][j - 1]);}if (c[i - 1][j] == S || c[i][j + 1] == S || c[i - 1][j + 1] == S) Init(S, x);}}f[S] = 1, que[hd = tl = 1] = S;while (hd <= tl) {int x = que[hd ++];RepE(i, x) {int y = g[i].y;(f[y] += f[x]) %= mod, in[y] --;if (!in[y]) que[++ tl] = y;}}return int(f[T] * num % mod);}
};

【TCO2013 Semifinal 2】 OneBlack相关推荐

  1. 【2012 Semifinal 1】 YetAnotherNim

    Description 现在有一个博弈游戏. 有n堆石子,每堆石子的数量在  之间,其中 . 先手先从中选出连续K堆石子,删掉其他的所有堆. 后手接着删去任意堆石子,可以不删,但是不能全删. 然后两人 ...

  2. 是否存在分布式的【大泥球】?

    2021-11-11 15:08 是否存在分布式的[大泥球]? 人们往往把微服务架构当成一剂良药,用以解决单体应用内的大泥球问题.然而,大泥球的本质问题是因为代码都位于同一个进程里运行的吗?换言之,如 ...

  3. 【课堂笔记系列】二进制

    一.你不知道的二进制? 1.接触二进制的时候,一定又在无聊犯困.这玩意有什么用处,学它干嘛?现在来告诉你吧! Eg:最常见却最熟视无睹的例子.电脑的分辨率到底是什么意思? 电脑的图像处理通过二进制,电 ...

  4. 【C/S语言】.net平台

    .net的学习 好像又复习了一遍VB和C#,没有具体看着视频写代码,只是通过看<VB.NET入门经典>粗学了一遍关于.net的知识! 基础 .net平台的出现: 当时的操作系统有多种如:w ...

  5. 算法设计与分析第4章 动态规划(二)【DP序列问题】

    第3章 动态规划(二)[DP序列问题] 3.2 DP序列问题 (51nod的动态规划教程很不错,讲解很详细,以下分析来自51nod) 1.矩阵取数问题 给定一个m行n列的矩阵,矩阵每个元素是一个正整数 ...

  6. java自适应table_【进阶之路】包罗万象——JAVA中的锁

    导言 大家好,我是练习java两年半时间的南橘,下面是我的微信,需要之前的导图或者想互相交流经验的小伙伴可以一起互相交流哦. 在Java中,我们能接触到各种各样的锁,而每种锁因其特性的不同,在不同的的 ...

  7. 仙居机器人_【101巨喜讯】又一个全国冠军!仙居学子机器人全国赛获奖啦!

    原标题:[101巨喜讯]又一个全国冠军!仙居学子机器人全国赛获奖啦! 仙居私家车广播 美丽仙居,品质广播!欢迎关注仙居最具品质广播微信公众号! 特大喜讯 ! 浙江仙居城峰中学.仙居机器人协会7名学生 ...

  8. 【python语言基础】疑难点整理2

    [python语言基础]疑难点整理1 第五章 在python语法中,循环体中的语句没有做限制,因此,可以是任何合法语句,当然也可以是循环语句.这样就形成了循环语句的嵌套. while循环语句和for循 ...

  9. 【ios开发/Xcode】使用UITableView完成学生信息及成绩的显示

    [ios开发/Xcode]使用UITableView完成学生信息及成绩的显示 设计思想 实现效果 源代码 设计思想 首先创建所有页面的故事版,包括,登录.注册与成绩页面 接着设置故事版的关联代码,如下 ...

最新文章

  1. com:向对象到面向服务
  2. 快速迭代的测试人员的思考
  3. python随机取列表元素_python random从集合中随机选择元素
  4. 权限操作-表结构分析与创建表
  5. SLAM--Pangolin显示相机位姿
  6. 蚂蚁课堂视频笔记思维导图-3期 九、分布式缓存架构
  7. VUE 身份证号验证
  8. rand和randc有什么区别
  9. U3D - TowerDefense
  10. vscode ssh遇到“过程试图写入的管道不存在”问题
  11. ng alain的简单使用
  12. 结构化数据和非结构化数据有何区别?
  13. 互联网公司分布式集群架构图入门解析(简单通俗易懂,超详细)
  14. linux下察看cpu状态
  15. CAD图纸版本太高怎么解决?CAD版本转换方法
  16. 使用SQL实现广告的精准投放
  17. JavaScript零基础知识点
  18. java实现环形链表解决约瑟夫环问题
  19. qt播放音乐报错DirectShowPlayerService::doSetUrlSource: Unresolved error code XXXXXX
  20. 宠辱不惊闲看庭前花开花落;去留无意漫观天外云展云舒

热门文章

  1. 〈原创〉诗如文学之筋骨,琴乃乐中之天籁
  2. stm32项目_stm32f103c8t6项目_循迹避障小车完整制作过程_智能小车设计_STM32智能小车教程-循迹-避障-蓝牙遥控-跟随
  3. leaflet 加载腾讯地图
  4. BERT实战(1):使用DistilBERT作为词嵌入进行文本情感分类,与其它词向量(FastText,Word2vec,Glove)进行对比
  5. 1. 【Part3】 Contour Detection and Hierarchical Image Segmentation【轮廓检测图像分割】
  6. 洛谷 P1719 最大加权矩形 (前缀和,动态规划)
  7. C语言-顺序表直接删除重复元素
  8. python逻辑运算符的优先级_Python逻辑运算符
  9. gradle自定义任务
  10. rk3288_5.1_BOX 调整HDMI屏幕满屏