1. 程式人生 > >BZOJ 1656 [Usaco2006 Jan] The Grove 樹木:bfs【射線法】

BZOJ 1656 [Usaco2006 Jan] The Grove 樹木:bfs【射線法】

family ring 連通 cnblogs max new div 題意 pop

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1656

題意:

  給你一個n*m的地圖,‘.‘表示空地,‘X‘表示樹林,‘*‘表示起點。

  所有‘X‘為一個連通塊。

  對於每一個點,你可以向周圍八個方向走,均算作一步。

  讓你找出一條路徑,能夠將所有‘X‘包圍。

  問你路徑最短為多少。

題解:

  bfs + 射線法。

  找出最上面(x坐標最小)的一個‘X‘,並向上方作一條射線,標記為‘#‘。

  從起點開始bfs,並且不能穿過射線(即‘#‘不能到達)。

  最後枚舉射線上的每一個點,令lef為左邊能夠一步到達當前點的最短路徑,rig同理。

  所以ans = min (lef + rig + 2)

AC Code:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <queue>
  5 #define MAX_N 55
  6 #define INF 1000000000
  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 Coor(int _x,int _y) 18 { 19 x=_x; 20 y=_y; 21 } 22 Coor(){} 23 }; 24 25 int n,m; 26 int ans=INF; 27 int dis[MAX_N][MAX_N]; 28 bool vis[MAX_N][MAX_N]; 29 char c[MAX_N][MAX_N]; 30 Coor start;
31 Coor tp; 32 queue<Coor> q; 33 34 void read() 35 { 36 cin>>n>>m; 37 for(int i=1;i<=n;i++) 38 { 39 for(int j=1;j<=m;j++) 40 { 41 cin>>c[i][j]; 42 if(c[i][j]==*) start=Coor(i,j); 43 } 44 } 45 } 46 47 void find_line() 48 { 49 tp=Coor(INF,INF); 50 for(int i=1;i<=n;i++) 51 { 52 for(int j=1;j<=m;j++) 53 { 54 if(c[i][j]==X && i<tp.x) tp=Coor(i,j); 55 } 56 } 57 for(int i=tp.x-1;i>0;i--) 58 { 59 c[i][tp.y]=#; 60 } 61 } 62 63 Coor get_front() 64 { 65 Coor now=q.front(); 66 q.pop(); 67 vis[now.x][now.y]=false; 68 return now; 69 } 70 71 void insert(Coor now) 72 { 73 if(vis[now.x][now.y]) return; 74 q.push(now); 75 vis[now.x][now.y]=true; 76 } 77 78 inline bool is_legal(int x,int y) 79 { 80 return x>0 && x<=n && y>0 && y<=m && c[x][y]!=X && c[x][y]!=#; 81 } 82 83 void bfs() 84 { 85 memset(dis,0x3f,sizeof(dis)); 86 memset(vis,false,sizeof(vis)); 87 insert(start); 88 dis[start.x][start.y]=0; 89 while(!q.empty()) 90 { 91 Coor now=get_front(); 92 int x=now.x; 93 int y=now.y; 94 for(int i=0;i<8;i++) 95 { 96 int nx=x+dx[i]; 97 int ny=y+dy[i]; 98 if(is_legal(nx,ny) && dis[nx][ny]>dis[x][y]+1) 99 { 100 dis[nx][ny]=dis[x][y]+1; 101 insert(Coor(nx,ny)); 102 } 103 } 104 } 105 } 106 107 void solve() 108 { 109 find_line(); 110 bfs(); 111 for(int i=tp.x-1;i>0;i--) 112 { 113 int x=i; 114 int y=tp.y; 115 int lef=min(dis[x][y-1],min(dis[x-1][y-1],dis[x+1][y-1])); 116 int rig=min(dis[x][y+1],min(dis[x-1][y+1],dis[x+1][y+1])); 117 ans=min(ans,lef+rig+2); 118 } 119 } 120 121 void print() 122 { 123 cout<<ans<<endl; 124 } 125 126 int main() 127 { 128 read(); 129 solve(); 130 print(); 131 }

BZOJ 1656 [Usaco2006 Jan] The Grove 樹木:bfs【射線法】