题目描述:

随着最后通牒的递出,C国的总攻也开始了,由于C国在地形上的优势,C国总司令下令采用水攻,剿灭A国最后的有生力量。

地形图是一个M*N的矩阵,矩阵上每一个点都对应着当前点的高度。C国总司令将选择若干个点进行放水(放水……这个词很好很强大嘛……)。根据水往低处流的特性,假设水只往东南西北一个单位一个单位的流动,A国的土地将很快的被淹没。HOWEVER,A国也不是一马平川的,所以总会有地方是淹没不到的。你的任务很简单,判断一下A国司令部会不会被淹没掉。
我们将给你完整的地形图,然后给出A国司令部所在位置,给出C国将在哪几个点进行放水操作。你所需要的,就是给出A国司令部会不会被水淹。IF被水淹了,那么就意味着,战争结束了,OTHERWISE,战争也会结束(八成被水包围了)……

输入描述:

第一行:一个整数K,代表数据组数。 对于每一组数据: 第一行:符合题目描述的两个整数,M(0<M<=200)、N(0<N<=200)。
第二~M+1行:每行N个数,以空格分开,代表这个矩阵上的各点的高度值H(0<=H<=1000)。
第M+2行:两个整数I(0<I<=M)、J(0<J<=N),代表司令部所在位置。
第M+3行:一个整数P(0<P<=M*N),代表放水点个数。
第M+4~M+P+4行:每行两个整数X(0<X<=M)、Y(0<Y<=N),代表放水点。

输出描述:

对于每组数据,输出一行,如果被淹则输出Yes,没有则输出No。

一道简单的bfs,交了好多次才过。。对每个放水点进行bfs,并且更新图(按理说不更新也没问题,但是还是更新的过了)

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int p[205][205], book[205][205], ex, ey, n, m;
int f[][2] = {0,1,1,0,0,-1,-1,0};
struct node{
  int x, y;
}now, Next;
int bfs(int x, int y) {
  book[x][y] = 1;
  if(x == ex && y == ey) return 1;
  now.x = x, now.y = y;
  queue<node>q;
  q.push(now);
  while(!q.empty()) {
    now = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      Next.x = now.x + f[i][0], Next.y = now.y + f[i][1];
      if(Next.x >= 1 && Next.y >= 1 && Next.x <= n&& Next.y <= m) {
        if(book[Next.x][Next.y] == 0 && p[Next.x][Next.y] <= p[x][y]) {
          p[Next.x][Next.y] = p[x][y];
          if(Next.x == ex && Next.y == ey) 
            return 1;
          book[Next.x][Next.y] = 1;
          q.push(Next);
        }
      }
    }
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int k;
  cin >> k;
  while(k--) {
    cin >> n >> m;
    for (int i = 1;i <= n; i++) 
      for (int j = 1; j <= m; j++) 
        cin >> p[i][j];
    cin >> ex >> ey;
    int flag = 0, t, x, y;
    cin >> t;
    while(t--) {
      cin >> x >> y;
      if(flag == 0) {
        memset(book, 0, sizeof(book));
        if(bfs(x, y)) {
          flag = 1;
        }
      }
    }
    if(flag == 1) cout << "Yes" << endl;
    else cout << "No" << endl;
  }
}