USACO的又一道搜索题

前置芝士

  1. BFS(DFS)遍历:用来搜索.(因为BFS好写,本文以BFS为准还不是因为作者懒)
  2. 链式前向星,本题的数据比较水,所以邻接表也可以写,但是链式前向星它不香吗.

具体做法

对于一个点,它可能有不止一个房间,虽然可以开一个\([x_1][y_1][x_2][y_2]\)的邻接矩阵,但是每次查询时需要\(\theta(N^2)\)枚举,十分的麻烦,还可能会T,这时就需要用到链式前向星来优化了,不仅优化了时间,还优化了空间,简直一举两得.这里的链式前向星的写法也很简单:

代码

struct Edge//定义一个结构体
{
int next;
int x,y;
}edge[maxM];
int cnt=0;
int _head[maxN][maxN];
void Add(Room a,Room b)//在房间a和房间b间添加一条边
{
edge[++cnt].x=b.x;
edge[cnt].y=b.y;
edge[cnt].next=_head[a.x][a.y];
_head[a.x][a.y]=cnt;
}
//一时define一时爽,一直define一直爽
#define For(x,y) for(int _i_=_head[x][y];_i_;_i_=edge[_i_].next)
#define X edge[_i_].x
#define Y edge[_i_].y

对于每个点它只会进一次队列,但是如果那时它的灯没有打开,不代表这个灯永远不会被打开,所以在每进入一个房间后需要判断被打开灯的房间是否被询问过,如果被询问过需要将这个点放入队列.

注意输出的是有多少个房间的灯可以被打开.

有一些具体的细节讲.

代码

#include<bits/stdc++.h>
#define rap(i,first,last) for(int i=first;i<=last;++i)
using namespace std;
const int maxN=105;
const int maxM=1e6+5;
const int move_x[5]={233,1,-1,0,0};
const int move_y[5]={233,0,0,1,-1};
int head=0,tail=1;
bool visit[maxN][maxN];
struct Que//队列
{
int x;
int y;
}que[maxN*maxN];//队列里最多N^2个房间,每个房间只会进一次
int N,M;
struct Room//对于房间再开一个结构体
{
int x,y;
};
//链式前向星
struct Edge
{
int next;
int x,y;
}edge[maxM];
int cnt=0;
int _head[maxN][maxN];
bool opened[maxN][maxN];
void Add(Room a,Room b)
{
edge[++cnt].x=b.x;
edge[cnt].y=b.y;
edge[cnt].next=_head[a.x][a.y];
_head[a.x][a.y]=cnt;
}
int answer=1;
#define For(x,y) for(int _i_=_head[x][y];_i_;_i_=edge[_i_].next)
#define X edge[_i_].x
#define Y edge[_i_].y
//
void Open(int x,int y)//打开一个房间的开关
{
For(x,y)
if(!opened[X][Y])//注意要有这个特判
{
opened[X][Y]=1;
answer++;//每打开一个灯answer++
if(visit[X][Y])//如果询问过就放入队列
{
que[++tail].x=X;
que[tail].y=Y;
}
}
}
int main()
{
scanf("%d%d",&N,&M);
Room room1,room2;
rap(i,1,M)
{
scanf("%d%d%d%d",&room1.x,&room1.y,&room2.x,&room2.y);
Add(room1,room2);//添加一条边
}
rap(i,1,N)visit[i][0]=visit[0][i]=visit[N+1][i]=visit[i][N+1]=1;//在四周打上标记
que[1].x=1;
que[1].y=1;
opened[1][1]=1;
while(++head<=tail)
{
Open(que[head].x,que[head].y);//在队头时打开比较方便,不会有遗漏
rap(i,1,4)
if(opened[que[head].x+move_x[i]][que[head].y+move_y[i]])//如果这个位置的灯被打开了
{
if(!visit[que[head].x+move_x[i]][que[head].y+move_y[i]])//没有询问过就放入队列
{
visit[que[head].x+move_x[i]][que[head].y+move_y[i]]=1;
que[++tail].x=que[head].x+move_x[i];
que[tail].y=que[head].y+move_y[i];
}
}
else
{
visit[que[head].x+move_x[i]][que[head].y+move_y[i]]=1;//没有被打开也要标记为询问过
}
}
printf("%d",answer);//输出answer
return 0;
}

「Luogu P2845 [USACO15DEC]Switching on the Lights 开关灯」的更多相关文章

  1. Luogu P2845 [USACO15DEC]Switching on the Lights 开关灯(bfs)

    P2845 [USACO15DEC]Switching on the Lights 开关灯 题意 题目背景 来源:usaco-2015-dec \(Farm\ John\)最近新建了一批巨大的牛棚.这 ...

  2. P2845 [USACO15DEC]Switching on the Lights 开关灯

    题目背景 来源:usaco-2015-dec Farm John 最近新建了一批巨大的牛棚.这些牛棚构成了一个N*N的矩形网络.(1<n<100) 然而bessie十分怕黑,他想计算可以把 ...

  3. 搜索【洛谷P2845】 [USACO15DEC]Switching on the Lights 开关灯

    P2845 [USACO15DEC]Switching on the Lights 开关灯 题目背景 来源:usaco-2015-dec Farm John 最近新建了一批巨大的牛棚.这些牛棚构成了一 ...

  4. 「Luogu P5494 【模板】线段树分裂」

    (因为没有认证,所以这道题就由Froggy上传) 线段树分裂用到的地方确实并不多,luogu上以前也没有这道模板题,所以就出了一道,实在是想不出怎么出模板了,所以这道题可能可以用一些其他的算法水过去. ...

  5. [Luogu 3128] USACO15DEC Max Flow

    [Luogu 3128] USACO15DEC Max Flow 最近跟 LCA 干上了- 树剖好啊,我再也不想写倍增了. 以及似乎成功转成了空格选手 qwq. 对于每两个点 S and T,求一下 ...

  6. 洛谷P2828 Switching on the Lights(开关灯)

    P2828 Switching on the Lights(开关灯) 题目背景 来源:usaco-2015-dec Farm John 最近新建了一批巨大的牛棚.这些牛棚构成了一个N*N的矩形网络.( ...

  7. bzoj4395[Usaco2015 dec]Switching on the Lights*

    bzoj4395[Usaco2015 dec]Switching on the Lights 题意: n*n个房间,奶牛初始在(1,1),且只能在亮的房间里活动.每当奶牛经过一个房间,就可以打开这个房 ...

  8. 洛谷P2845-Switching on the Lights 开关灯

    Problem 洛谷P2845-Switching on the Lights 开关灯 Accept: 154    Submit: 499Time Limit: 1000 mSec    Memor ...

  9. FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...

随机推荐

  1. 4_3 救济金发放(UVa133)<子过程/函数设计>

    为了缩短领救济品的队伍,NNGLRP决定了以下策略:每天所有来申请救济品的人会被放在一个大圆圈,面朝里面.标明一个人为编号1号,其他的就从那个人开始逆时针开始编号直到N.一个官员一开始逆时针数,数k个 ...

  2. selenium 元素查找与属性

    1.首先你要安装selenium库啦 pip install selenium 2.selenium查找元素就八种方法 from selenium import webdriver driver=we ...

  3. 201771010135杨蓉庆 《面对对象程序设计(java)》第八周学习总结

    1.实验目的与要求 (1) 掌握接口定义方法: (2) 掌握实现接口类的定义要求: (3) 掌握实现了接口类的使用要求: (4) 掌握程序回调设计模式: (5) 掌握Comparator接口用法: ( ...

  4. 201771010135杨蓉庆《面向对象程序设计(java)》第四周学习总结

    学习目标 1.掌握类与对象的基础概念,理解类与对象的关系: 2.掌握对象与对象变量的关系: 3.掌握预定义类的基本使用方法,熟悉Math类.String类.math类.Scanner类.LocalDa ...

  5. Python基础模块整理

    1.shutil   :可以用来对文件进行基本操作(拷贝,剪切等) 2.glob    :提供了一个函数用于从目录通配符搜索中生成文件列表 3.datetime    :日期和时间的处理 4.zlib ...

  6. 【原】mac电脑使用总结

    mac下终端配置(item2+oh-my-zsh)+solarized配色方案:https://www.cnblogs.com/weixuqin/p/7029177.html

  7. 水平居中显示CSS

    HTML代码部分 <div class="center" > <img style="margin:0 auto ;" :src=item.i ...

  8. golang数据库操作初体验

    在golang中,提供了标准的数据库接口database/sql包,做过数据库开发的应该知道,不同的数据库有不同的数据库驱动.比如mysql等,我们可以去找 https://golang.org/s/ ...

  9. python知识点总结以及15道题的解析

    先看知识点总结 一.序列操作符x in s 如果x是列表s的元素,返回True,否则Falses + t 连接两个序列s和ts*n或者n*s 将序列s复制n次s[i] 返回s中第i元素s[i:j]或s ...

  10. UINavigationController+FDFullscreenPopGesture全屏回滑手势阅读理解

    滑动返回纯oc.纯swifthttps://github.com/Bonway/BBGestureBack UINavigationController+FDFullscreenPopGesture全 ...