(File IO): input:light.in output:light.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
最近正在修建一个巨大的包含
个房间的牲口棚,这些房间从
标号到
。由于某些原因而害怕黑暗,贝茜这头奶牛想要尽可能地开更多房间的灯。贝茜从房间
出发,这个房间是唯一一个一开始就亮着的房间。在一些房间中,她会找到一些电灯开关,这些开关她可以用来切换其他房间的灯的状态。比如,在
这个房间中可能存在一个电灯开关来控制
房间中的电灯。贝茜只能进电灯开着的房间,并且贝茜只能从房间(x,y)走到四个方向的房间
(如果在边界的话,那可能会更少)。请帮忙统计贝茜最多可以照亮多少房间。
输入
第一行两个整数
下面
行,每行用四个整数
来表示房间
存在着可以控制房间
的灯的开关。一个房间可能有多个开关,一个房间的灯的开关可能存在于多个房间中。
输出
一行一个整数,表示贝茜最多可以照亮的房间数
样例输入
3 6
1 1 1 2
2 1 2 2
1 1 1 3
2 3 3 1
1 3 1 2
1 3 2 1
样例输出
5
数据范围限制
提示
在这个样例中,贝茜可以使用房间
内的开关打开房间
和
的灯。然后她可以走到
,使用
内的开关打开
的灯,接着可以通过
打开
的灯,然而
是黑暗的,她无法去打开
房间里的开关,因此,她最多只能打开
个房间里的灯。
解题思路
这题就是广搜:
①枚举肯定不能去
的去找,所以要用二维邻接表 。。
②广搜:
(1)每次加入队列的点要求能从
到达
(2)每搜完一次就将队列里的坐标拿出来枚举
周看一下有没有可以加入队列的,保证没有缺漏。。
代码
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<string>
#include<iomanip>
#include<cmath>
using namespace std;
const int dx[5]={0,1,-1,0,0};
const int dy[5]={0,0,0,1,-1};
int n,m,ans,h,t,xy;
int a[110][110],x[20010],y[20010],xx[20010],yy[20010],next[20010],q[20010][3];
bool p[110][110],dis[110][110];
void bfs()
{
h=0,t=1;
q[1][1]=1;
q[1][2]=1;
dis[1][1]=1;
p[1][1]=1;
while(h<t)
{
h++;
xy=a[q[h][1]][q[h][2]];
while(xy>0)
{
dis[xx[xy]][yy[xy]]=1;
xy=next[xy];
}
for(int i=1;i<=h;i++)
for(int j=1;j<=4;j++)
if(dis[q[i][1]+dx[j]][q[i][2]+dy[j]])
{
if(!p[q[i][1]+dx[j]][q[i][2]+dy[j]])
{
t++;
q[t][1]=q[i][1]+dx[j];
q[t][2]=q[i][2]+dy[j];
p[q[i][1]+dx[j]][q[i][2]+dy[j]]=1;
}
}
}
}
int main(){
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x[i],&y[i],&xx[i],&yy[i]);
next[i]=a[x[i]][y[i]];
a[x[i]][y[i]]=i;
}
bfs();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(dis[i][j])
ans++;
printf("%d",ans);
}