BZOJ 1619 [Usaco2008 Nov]Guarding the Farm 保卫牧场:dfs【灌水】

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1619

题意:

  给你一个n*m的地形图,位置(x,y)的海拔为h[x][y]。

  一个山顶的定义为:可以是一个点,或是一片海拔相同的区域。

           要求为山顶周围(每个点的八个方向)的海拔均比山顶低(或为边界)。

  问你有多少个山顶。

 

题解:

  dfs灌水法。

 

  将所有点按海拔从高到低排序。

  依次从每个点灌水,水流到的地方做标记。

  灌水:如果一个点有水,则它周围海拔比它低的点也会被水淹。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <vector>
 6 #define MAX_N 705
 7 
 8 using namespace std;
 9 
10 const int dx[]={-1,1,0,0,-1,-1,1,1};
11 const int dy[]={0,0,-1,1,-1,1,-1,1};
12 
13 struct Coor
14 {
15     int x;
16     int y;
17     int t;
18     Coor(int _x,int _y,int _t)
19     {
20         x=_x;
21         y=_y;
22         t=_t;
23     }
24     Coor(){}
25     friend bool operator < (const Coor &a,const Coor &b)
26     {
27         return a.t>b.t;
28     }
29 };
30 
31 int n,m;
32 int ans=0;
33 int h[MAX_N][MAX_N];
34 bool vis[MAX_N][MAX_N];
35 vector<Coor> v;
36 
37 void read()
38 {
39     cin>>n>>m;
40     memset(h,-1,sizeof(h));
41     for(int i=1;i<=n;i++)
42     {
43         for(int j=1;j<=m;j++)
44         {
45             cin>>h[i][j];
46             v.push_back(Coor(i,j,h[i][j]));
47         }
48     }
49 }
50 
51 inline bool is_legal(int x,int y)
52 {
53     return x>0 && x<=n && y>0 && y<=m && !vis[x][y];
54 }
55 
56 void dfs(int x,int y)
57 {
58     vis[x][y]=true;
59     for(int i=0;i<8;i++)
60     {
61         int nx=x+dx[i];
62         int ny=y+dy[i];
63         if(is_legal(nx,ny))
64         {
65             if(h[x][y]>=h[nx][ny])
66             {
67                 dfs(nx,ny);
68             }
69         }
70     }
71 }
72 
73 void solve()
74 {
75     sort(v.begin(),v.end());
76     memset(vis,false,sizeof(vis));
77     for(int i=0;i<v.size();i++)
78     {
79         Coor now=v[i];
80         if(!vis[now.x][now.y])
81         {
82             dfs(now.x,now.y);
83             ans++;
84         }
85     }
86 }
87 
88 void print()
89 {
90     cout<<ans<<endl;
91 }
92 
93 int main()
94 {
95     read();
96     solve();
97     print();
98 }

 

转载于:https://www.cnblogs.com/Leohh/p/7612402.html

展开阅读全文
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值