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 }