bzoj4395(技巧BFS)

来源:互联网 发布:淘宝买家旺旺名 编辑:程序博客网 时间:2024/05/16 17:11


看网上的题解都是,不停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;}

0 0
原创粉丝点击