[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\) 格可以任意指定走出方 ...
随机推荐
- Nginx 限制php解析、限制浏览器访问
限制php解析 1.有时候会根据目录来限制php解析: location ~ .*(diy|template|attachments|forumdata|attachment|image)/.*\.p ...
- 20145222黄亚奇《网络对抗》MSF基础应用
实践目标 掌握metasploit的基本应用方式. 具体需要完成(1)ms08_067;(2)ms11_050:(3)Adobe(4)成功应用任何一个辅助模块. 实验内容 掌握metasploit的基 ...
- [BZOJ2342]双倍回文
对每个大中心暴力找小中心即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #define ...
- Idea中解决Git中pull代码内容冲突
Git开发中,由于项目开发人员不只一个,所以在代码开发中,多个开发人员可能会对同一文件同一地方的代码进行修改,这样在先后提交到master上时,就会产生冲突,以下是演示冲突产生和解决冲突的示例: 1. ...
- NOIP2018没有什么新闻
noip结束了.站在六中门口,回头望了一眼偌大的校园,萧瑟的秋风卷起残败的落叶,纷纷扬扬地洒落,洒落在OIer的心头. 今年的noip没有什么新闻,有的只是又一次被喷的题,和又一次挂掉的我. Day ...
- LuManager升级php5.6.27方法
LuManager自带的PHP在FastCGI模式是 5.2.17版,非FastCGI模式是 5.3.14版.由于360网盘的停服,已不敢再用那些免费的网盘,干脆自己搭个私有云.查了下相关资料准备先试 ...
- eclipse——反编译插件
百度云链接 链接:https://pan.baidu.com/s/1iEtstiK5mJ4kDp6gTfVBww 密码:8wf7 在线安装地址 http://jd.benow.ca/jd-eclips ...
- C语言查找算法之顺序查找、二分查找(折半查找)
C语言查找算法之顺序查找.二分查找(折半查找),最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 顺序查找 /*顺序查找 顺序查找是在一个已知无(或有序)序队列中找出与给定关键字相同的 ...
- TCP异步IO_服务端_测试
1.测试代码来自于 JDK7 AIO初体验 http://www.iteye.com/topic/1113611 1.1. package aio; import java.net.InetSocke ...
- 关于C语言中结构体大小计算
结构体大小的计算,.网上说法一大堆还都不一样分什么对齐不对齐,偏移量什么的.. 在此稍微举例简单总结下: 对齐原则:每一成员的结束偏移量需对齐为后一成员类型的倍数 补齐原则:最终大小补齐为成员中最大 ...