洛谷P1141 01迷宫(bfs)

本废物的第一篇博客,正好在写这道题,就拿来练练手了。也就写写这种基础题目了

传送门https://www.luogu.org/problemnew/show/P1141

  裸上bfs会TLE,我们可以发现同一个连通图上的点的答案应该是一样的。所以选择用连通图来优化一下,速度超级加倍。

  代码如下:

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 int map[1005][1005];
 6 int flag[1005][1005],ans[1000005];//ans一定要开大一点 因为坐标可以有1e6种。
 7 int toward[4][2]={0,1,0,-1,1,0,-1,0};
 8 int n,m;
 9 struct node{
10     int x,y;
11 }p,head;
12 int bfs(int x,int y,int cnt){//我用了队列来写bfs,实际上数组也是ok的,有空更新数组写法,本质上是一样的。
13     int ans=1;
14     queue<node> q;
15     p.x=x;
16     p.y=y;
17     q.push(p);
18     while(!q.empty()){
19         head=q.front();
20         q.pop();
21         for(int i=0;i<4;i++){
22             p.x=head.x+toward[i][0];
23             p.y=head.y+toward[i][1];
24             if(p.x<1||p.x>n||p.y<1||p.y>n||flag[p.x][p.y]!=0)
25                 continue;
26             else{
27                 if(map[p.x][p.y]!=map[head.x][head.y]){
28                     //book[p.x][p.y]=1;
29                     q.push(p);
30                     flag[p.x][p.y]=cnt;
31                     ans++;
32                 }
33             }
34         }
35     }
36     return ans;
37 }
38 int main(){
39     char t[1005];
40     scanf("%d %d",&n,&m);
41     for(int i=1;i<=n;i++){
42         scanf("%s",t);
43         for(int j=1;j<=n;j++){
44             map[i][j]=t[j-1]-'0';//把坐标从字符串换成数字,不做这步也可以,下面的代码需要稍微改动。
45         }
46     }
47     memset(flag,0,sizeof(flag));
48     int cnt=0;
49     for(int i=1;i<=n;i++){
50         for(int j=1;j<=n;j++){
51             if(flag[i][j]==0){
52                 flag[i][j]=++cnt;
53                 ans[cnt]=bfs(i,j,cnt);
54             }
55         }
56     }
57     int x,y;
58     for(int i=0;i<m;i++){
59         scanf("%d %d",&x,&y);
60         printf("%d\n",ans[flag[x][y]]);
61     }
62     return 0;
63 }

 

posted @ 2019-07-17 19:45  Obake  阅读(361)  评论(2编辑  收藏  举报