看网上的题解都是,不停bfs直到不再更新,感觉这样常数会大一些。
实际上我们能够到达一个点,1:到达过他的相邻点,2:他的灯被打开了
那么我们就维护两个bool型数组,一个判断是否到达相邻点,一个判断灯是否打开,只有当两个条件都成立的时候才把该位置加进队列里面去
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline int read()
{
int ans;char ch;
while ((ch=getchar())<'0'||ch>'9') ;ans=ch-'0';
while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0';
return ans;
}
const int qx[]={0,0,1,-1};
const int qy[]={1,-1,0,0};
int n,m;
int head[105][105],tot;
struct aa {int x,y,pre;}a[200005];
void addedge(int g,int b,int c,int d) {a[++tot].x=c,a[tot].y=d;a[tot].pre=head[g][b];head[g][b]=tot;}
bool t1[105][105],t2[105][105],b[105][105];
queue<aa> q;
int main()
{
n=read(),m=read();
int gg,bb,cc,dd;
for (int i=1;i<=m;i++)
{
gg=read(),bb=read(),cc=read(),dd=read();
addedge(gg,bb,cc,dd);
}
int ans=1,x,y;
queue<aa> q;
q.push((aa){1,1,0});
t1[1][1]=t2[1][1]=true;
while (!q.empty())
{
aa u=q.front();q.pop();
x=u.x,y=u.y;
for (int i=head[x][y];i;i=a[i].pre)
if (!t1[a[i].x][a[i].y])
{
if (t2[a[i].x][a[i].y])
q.push((aa){a[i].x,a[i].y,0});
t1[a[i].x][a[i].y]=true;ans++;
}
for (int i=0;i<4;i++)
if (!t2[x+qx[i]][y+qy[i]])
{
if (t1[x+qx[i]][y+qy[i]])
q.push((aa){x+qx[i],y+qy[i],0});
t2[x+qx[i]][y+qy[i]]=true;
}
}
printf("%d",ans);
return 0;
}