- 思路:先DFS找出物理意义上的连通块,即在一起的沙子。然后对于每一块沙子,从其所在的连通块分别向其下方沙子,左下方沙子,右下方沙子所在连通块连边,然后跑tarjan缩点,再统计入度为0的点即为答案。
- #11一直RE,但CF上输出了数字,并且输出的是正确的。自己对拍出的RE数据,单步调试到最后居然又输出了一个正确的结果!
- 各位巨佬们,救救孩子吧,孩子已经快受不了了
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
x=0;
int y=1;
char a;
a=getchar();
while(a<'0'||a>'9'){
if(a=='-')y=-1;
a=getchar();
}
while(a>='0'&&a<='9'){
x=x*10+a-'0';
a=getchar();
}
x*=y;
}
int n,m;
string f[400008],fz[400008];
int ft;
int qfz[400008];
void dfsq(int x,int y,int a){
f[x][y]='.';
qfz[(x-1)*m+y]=a;
if(f[x+1][y]=='#')dfsq(x+1,y,a);
if(f[x-1][y]=='#')dfsq(x-1,y,a);
if(f[x][y+1]=='#')dfsq(x,y+1,a);
if(f[x][y-1]=='#')dfsq(x,y-1,a);
}
int fans;
vector<int>fc[400008];
int dfn[400008],low[400008];
int cqfz,top,cnt;
int fsta[400008],ins[400008];
int c[400008];
void tarjan(int x){
dfn[x]=low[x]=++cqfz;
fsta[++top]=x,ins[x]=1;
for(int i=0;i<fc[x].size();++i){
int y=fc[x][i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y])low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
++cnt;int y;
do{
y=fsta[top--],ins[y]=0;
c[y]=cnt;
}while(x!=y);
}
}
vector<int>ffi[400008];
int fd[400008];
int main(){
read(n);read(m);
for(int i=1;i<=n;++i){
cin>>f[i];
f[i]=" "+f[i];
fz[i]=f[i];
}
for(int i=1;i<=m;++i){
int a;
read(a);
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(f[i][j]=='#'){
++ft;
dfsq(i,j,ft);
}
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(fz[i][j]=='#'){
int x=qfz[(i-1)*m+j];
int kk=n;
for(int k=i+1;k<=n;++k){
if(fz[k][j]=='#'){
if(qfz[(k-1)*m+j]!=x)fc[x].push_back(qfz[(k-1)*m+j]);
kk=k;
break;
}
}
for(int l=i;l<=kk;++l){
if(fz[l][j+1]=='#'){
if(qfz[(l-1)*m+j+1]!=x)fc[x].push_back(qfz[(l-1)*m+j+1]);
break;
}
}
for(int l=i;l<=kk;++l){
if(fz[l][j-1]=='#'){
if(qfz[(l-1)*m+j-1]!=x)fc[x].push_back(qfz[(l-1)*m+j-1]);
break;
}
}
}
}
}
for(int i=1;i<=ft;++i){
if(!dfn[i])tarjan(i);
}
for(int i=1;i<=ft;++i){
for(int j=0;j<fc[i].size();++j){
int y=fc[i][j];
if(c[i]==c[y])continue;
ffi[c[i]].push_back(c[y]);
}
}
int ffff=0;
for(int i=1;i<=ft;++i)ffff=max(ffff,c[i]);
for(int i=1;i<=ffff;++i){
for(int j=0;j<ffi[i].size();++j){
int y=ffi[i][j];
++fd[y];
}
}
for(int i=1;i<=ffff;++i){
if(fd[i]==0)++fans;
}
cout<<fans<<endl;
return 0;
}