首先,对于一个在第 \(i\) 行 \(j\) 列的沙子,如果他开始下降,他能够使哪些沙子下降呢?

很容易得知是第 \(j-1,j,j+1\) 列所有行号不小于 \(i\) 的沙子。

对于沙子 \(u\) 下降能够使沙子 \(v\) 下降,我们连一条边 \((i,j)\)。然后缩点,对于度数为 \(0\) 的点,我们他不可能因为别的沙子下降而下降,所以我们得手动扰动这些沙子。

那么答案就是缩点后的图中度数为 \(0\) 的点的个数。

然而暴力连边的时空复杂度是 \(O(n^2m)\) 的,我们考虑省掉一些不要的边。

对于三个点 \((u,v,w)\),若存在边 \((u,v)\) 和 \((v,w)\),那么边 \((u,w)\) 明显可以被省掉。

根据这个优化,我们可以省掉很多边。

比如对于三个点 \(u,v,w\),其中 \(v\) 在 \(u\) 的左下方,\(w\) 在 \(v\) 正下方,那么 \(u\) 很明显只需要连接 \(v\) 而不需要连接 \(w\)。

所以,对于一个点,需要连接这些边:

  1. 若 \((i,j)\) 有一块沙子且 正上方一格 也有一块沙子,连接 \((i,j)\) 和 \((i-1,j)\);
  2. 若 \((i,j)\) 的正下方存在沙子,连接正下方第一块沙子;
  3. 若 \((i,j)\) 的下一列的下方存在沙子,连接下一列的下方第一块沙子;
  4. 若 \((i,j)\) 的上一列的下方存在沙子,连接上一列的下方第一块沙子;

对于 \(3\) 类边和 \(4\) 类边,反过来从左上/右上第一个沙子连接自己,预处理正上方第一块沙子即可。

当然也可以预处理正下方的第一块沙子,然后不反过来。

code:

#include<cstdio>
#include<vector>
const int M=4e5+5;
int n,m,ans,dfc,BCC,in[M],on[M],bl[M],dfn[M],low[M];std::vector<int>G[M];
bool val[M],istk[M];int top,stk[M];
inline int id(const int&x,const int&y){
return x?(x-1)*m+y:0;
}
inline int min(const int&a,const int&b){
return a>b?b:a;
}
inline char read_c(){
char s;while(s=getchar(),s!='.'&&s!='#');
return s;
}
void Tarjan(int u){
istk[stk[++top]=u]=true;
low[u]=dfn[u]=++dfc;
for(int&v:G[u]){
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(istk[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
register int v;++BCC;
do bl[v=stk[top--]]=BCC,istk[v]=false;while(v!=u);
}
}
signed main(){
register int i,j,lst;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i){
for(j=1;j<=m;++j){
on[id(i,j)]=(val[id(i,j)]=read_c()=='#')?id(i,j):on[id(i-1,j)];
}
}
for(j=1;j<=m;++j){
lst=0;
for(i=n;i>=1;--i){
if(!val[id(i,j)])continue;
if(lst)G[id(i,j)].push_back(lst);lst=id(i,j);
if(val[id(i-1,j)])G[id(i,j)].push_back(id(i-1,j));
if(j!=1&&on[id(i,j-1)])G[on[id(i,j-1)]].push_back(id(i,j));
if(j!=m&&on[id(i,j+1)])G[on[id(i,j+1)]].push_back(id(i,j));
}
}
for(i=1;i<=n*m;++i)if(!dfn[i]&&val[i])Tarjan(i);
for(i=1;i<=n*m;++i){
for(int&v:G[i])if(bl[v]!=bl[i])++in[bl[v]];
}
for(i=1;i<=BCC;++i)ans+=!in[i];
printf("%d\n",ans);
}

CF1534F1题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. VC 获取已系统安装的字体

    转载请注明来源:https://www.cnblogs.com/hookjc/ BOOL CALLBACK EnumFonts(CONST LOGFONT* lplf, CONST TEXTMETRI ...

  2. Java 自定义窗体(标题栏、窗体背景)

    感谢大佬:https://blog.csdn.net/ltx06/article/details/28996839 最近在书上看到这篇文章,觉得挺有意思.与大家分享一下,具体可以参见明日科技出版的&l ...

  3. dealloc方法

    dealloc方法基本概念 当一个对象的引用计数器值为0时,这个对象即将被销毁,其占用的内存被系统回收 对象即将被销毁时系统会自动给对象发送一条dealloc消息 (因此, 从dealloc方法有没有 ...

  4. [转]有关ListIterator接口的add与remove方法探究

    原文地址: http://www.java123.net/v/492971.html 应用案例: http://820199753.iteye.com/blog/2230032 ListIterato ...

  5. docker平时使用异常记录

    GPU主机重启后,启动使用GPU的容器报错 docker: Error response from daemon: Unknown runtime specified nvidia. 解决办法:修改/ ...

  6. LeetCode随缘刷题之赎金信

    欢迎评论区讨论. package leetcode.day_12_04; /** * 为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思. * * 给你一个赎金信 (ransom ...

  7. java+selenium脚本编写规范

    2.    源文件规范 2.1    文件名 源文件以最顶层的类名来命名,大小写敏感,文件扩展名为.java 2.2    文件编码 UTF-8 源文件要求编码格式为UTF-8 2.3    源文件结 ...

  8. HTML5知识点笔记

    1.HTML是一种标记语言 2.HTML元素不区分大小写  //可以在xss绕过waf时使用 3.<code></code>为空元素标签 <code/>为自闭合标签 ...

  9. suse 12 二进制部署 Kubernetets 1.19.7 - 第10章 - 部署kube-proxy组件

    文章目录 1.10.部署kube-proxy 1.10.0.创建kube-proxy证书 1.10.1.生成kube-proxy证书和秘钥 1.10.2.创建kube-proxy的kubeconfig ...

  10. JUC并发工具类之 CyclicBarrier同步屏障

    首先看看CyclicBarrier的使用场景: 10个工程师一起来公司应聘,招聘方式分为笔试和面试.首先,要等人到齐后,开始笔试:笔试结束之后,再一起参加面试.把10个人看作10个线程,10个线程之间 ...