[BZOJ5133][CodePlus2017年12月]白金元首与独舞
题意
给你一个\(n*m\)的网格,每个位置上有一个箭头指向上或下或左或右。有些位置上还没有箭头,现在要求你在这些没有箭头的位置上填入箭头,使得从网格的任意一个位置开始,都可以沿着箭头走出网格。
求填入的方案数膜\(10^9+7\)
sol
给“网格外”建一个点。每个格子向它指向的格子连一条边。
这样会发现一个方案合法当且仅当连出的这\(n*m\)条边构成一棵树。
没有确定的格子可以向四个方向连边。这样直接上矩阵树可以做到\(O((nm)^3)\)。
考虑优化。只对所有未确定的格子以及“网格外”建点,这样就只有\(k+1\)个点。每个未确定的格子向四个方向能走到的第一个未确定格子或是“网格外”连边。
具体实现可以用记搜,同时记录一下每个状态是否在搜索栈中,可以判无解。
复杂度是\(O(nm+k^3)\)
code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 305;
const int mod = 1e9+7;
int T,n,m,tot,id[N][N],f[N][N],vis[N][N],fg,a[N][N],ans;char s[N][N];
void init()
{
tot=fg=ans=1;
memset(id,0,sizeof(id));
memset(f,-1,sizeof(f));
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
}
int dfs(int i,int j)
{
if (~f[i][j]) return f[i][j];
if (i<1||i>n||j<1||j>m) return 1;
if (id[i][j]) return f[i][j]=id[i][j];
if (vis[i][j]) return f[i][j]=fg=0;vis[i][j]=1;
if (s[i][j]=='L') f[i][j]=dfs(i,j-1);
if (s[i][j]=='R') f[i][j]=dfs(i,j+1);
if (s[i][j]=='U') f[i][j]=dfs(i-1,j);
if (s[i][j]=='D') f[i][j]=dfs(i+1,j);
vis[i][j]=0;return f[i][j];
}
void link(int u,int v){a[u][v]--;a[v][v]++;}
int main()
{
freopen("dancestep.in","r",stdin);
freopen("dancestep.out","w",stdout);
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);init();
for (int i=1;i<=n;++i)
{
scanf("%s",s[i]+1);
for (int j=1;j<=m;++j)
if (s[i][j]=='.') id[i][j]=++tot;
}
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
dfs(i,j);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
if (id[i][j])
{
link(dfs(i,j-1),id[i][j]);link(dfs(i,j+1),id[i][j]);
link(dfs(i-1,j),id[i][j]);link(dfs(i+1,j),id[i][j]);
}
if (!fg) {puts("0");continue;}
for (int i=1;i<=tot;++i)
for (int j=1;j<=tot;++j)
a[i][j]=(a[i][j]+mod)%mod;
for (int i=2;i<=tot;++i)
{
for (int j=i+1;j<=tot;++j)
while (a[j][i])
{
int t=a[i][i]/a[j][i];
for (int k=i;k<=tot;++k) a[i][k]=(a[i][k]-1ll*t*a[j][k]%mod+mod)%mod,swap(a[i][k],a[j][k]);
ans=(mod-ans)%mod;
}
ans=1ll*ans*a[i][i]%mod;
}
printf("%d\n",ans);
}
}
[BZOJ5133][CodePlus2017年12月]白金元首与独舞的更多相关文章
- 【BZOJ5133】[CodePlus2017年12月]白金元首与独舞 矩阵树定理
[BZOJ5133][CodePlus2017年12月]白金元首与独舞 题面:www.lydsy.com/JudgeOnline/upload/201712/div1.pdf 题解:由于k很小,考虑用 ...
- 【bzoj5133】[CodePlus2017年12月]白金元首与独舞 并查集+矩阵树定理
题目描述 给定一个 $n\times m$ 的方格图,每个格子有 ↑.↓.←.→,表示从该格子能够走到相邻的哪个格子.有一些格子是空着的,需要填上四者之一,需要满足:最终的方格图中,从任意一个位置出发 ...
- [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞
[LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...
- BZOJ5131: [CodePlus2017年12月]可做题2
BZOJ没有题面,差评 洛谷的题目链接 题解 其实这题很久之前就写了,也想写个题解但是太懒了,咕到了今天 在typora写完题解不想copy过来再改格式了,于是直接贴截图qwq #include &l ...
- 【LibreOJ】#6259. 「CodePlus 2017 12 月赛」白金元首与独舞
[题目]给定n行m列的矩阵,每个位置有一个指示方向(上下左右)或没有指示方向(任意选择),要求给未定格(没有指示方向的位置)确定方向,使得从任意一个开始走都可以都出矩阵,求方案数.n,m<=20 ...
- 「CodePlus 2017 12 月赛」白金元首与独舞
description 题面 data range \[ 1 \leq T \leq 10, 1 \leq n, m \leq 200 , 0 \leq k \leq \min(nm, 300)\] ...
- 走进矩阵树定理--「CodePlus 2017 12 月赛」白金元首与独舞
n,m<=200,n*m的方阵,有ULRD表示在这个格子时下一步要走到哪里,有一些待决策的格子用.表示,可以填ULRD任意一个,问有多少种填法使得从每个格子出发都能走出这个方阵,答案取模.保证未 ...
- loj6259「CodePlus 2017 12 月赛」白金元首与独舞
分析 我们将没连的点连向周围四个点 其余的按照给定的方向连 我们将所有连出去的位置统一连到0点上 再以0作为树根 于是就将问题转化为了有向图内向树计数 代码 #include<iostream& ...
- Solution -「Code+#2」「洛谷 P4033」白金元首与独舞
\(\mathcal{Description}\) link. 给定一个 \(n\times m\) 的网格图,一些格子指定了走出该格的方向(上下左右),而有 \(k\) 格可以任意指定走出方 ...
随机推荐
- 【Flask】WTForms文件上传下载
# 文件上传笔记:1. 在模版中,form表单中,需要指定`encotype='multipart/form-data'`才能上传文件.2. 在后台如果想要获取上传的文件,那么应该使用`request ...
- Hbase:简单介绍一下Hbase表的结构
HBase 是一个NoSQL数据库,用于处理海量数据,可以支持10亿行百万列的大表,下面我就和大家分享一下数据是如何存放在HBase表中的 为了更好的理解HBase表的思路,先回顾一下关系数据库中表的 ...
- 最简单的CI框架入门示例--数据库取数据
前提: 安装好MySQL,Apache,PHP. 1.下载CI框架 下载地址 http://www.codeigniter.com/ 2.配置 database.php配置: 为数据库服务器设 ...
- 低版本C++ string的万能转换,从long string 之间的转换来看看
string 转 long 那必须是万年atoi(),不过得配合c_str()使用! [plain] view plain copy #include <string> #include ...
- ScrollView嵌套使用ListView冲突的解决与分析
因为ScrollView与ListView都是具有滚动条的控件,所以嵌套在一起使用的时候可能会出现事件的冲突,比如我就遇见了ListView中只显示一条数据的问题.解决的办法,就是自定义了一个List ...
- Android 必须知道2018年流行的框架库及开发语言,看这一篇就够了!
导语 2017 已经悄悄的走了,2018 也已经匆匆的来了,我们在总结过去的同时,也要展望一下未来,来规划一下今年要学哪些新技术.这几年优秀Android的开源库不断推出,新技术层出不穷,需要我们不断 ...
- Java泛型中的标记符含义
Java泛型中的标记符含义: E - Element (在集合中使用,因为集合中存放的是元素) T - Type(Java 类) K - Key(键) V - Value(值) N - Number ...
- UIElement.IsMouseCaptured属性的应用
一个只读属性,该值描述了此元素是否捕获到了鼠标,如果该值为true,则说明此元素捕获到了鼠标:否则,未捕获到(例如:当鼠标进入到一个Button的可视化范围之内,当Button按钮外观效果发生了变化时 ...
- python面向对象编程 继承 组合 接口和抽象类
1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...
- mongodb底层存储和索引原理——本质是文档数据库,无表设计,同时wiredTiger存储引擎支持文档级别的锁,MMAPv1引擎基于mmap,二级索引(二级是文档的存储位置信息『文件id + 文件内offset 』)
MongoDB是面向文档的数据库管理系统DBMS(显然mongodb不是oracle那样的RDBMS,而仅仅是DBMS). 想想一下MySQL中没有任何关系型数据库的表,而由JSON类型的对象组成数据 ...