本文鏈接:http://www.cnblogs.com/Ash-ly/p/5398867.html
題意:
中國和印度之間有一片地方,把這片地方抽象化,于是就可以看成一個N * M矩陣,其中黑色的代表高山不能走過去,白色的代表平原,可以通行,人每次可以選擇往上下左右四個方向移動,但是隨著時間的變化某些白色的平原會變成黑色的高山,從而變為不可通行,題目中給出一個代表地勢的圖,然后有 Q 次操作,第 i 次操作 代表在第 i 年?(x, y)處的平原變成了高山,即白色變為了黑色。問中國印度最早徹底斷絕的時間,如果在 Q 年后還沒有斷絕就輸出 -1;
思路:
對于0 - Q年份進行二分,然后利用BFS枚舉起點判斷連通性。如果在mid年時隔絕已經形成,那么說明答案在[lo-mid]之間,繼續二分,否則說明答案在(mid,hi]之間。
代碼:
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; const int MAXN = 500; int Gra[MAXN + 7][MAXN + 7]; int Date[MAXN + 7][MAXN + 7]; int stpX[] = {1, 0, 0, -1};//下一個狀態(方向) int stpY[] = {0, 1, -1, 0}; int visited[MAXN + 7][MAXN + 7];//標記點是否被訪問 int n, m; int flag;struct Point{int x;int y; }pt[MAXN * MAXN + 7];int chage(int x, int y) {return (x - 1) * m + y; }void BFS()//BFS判斷連通性 {memset(visited, 0, sizeof(visited));queue<Point> ptQu;struct Point pi;for(int i = 1; i <= m ; i++)//枚舉起點{if(Date[1][i] == 1 || visited[1][i]) continue;visited[1][i]= 1;pi.x = 1;pi.y = i;ptQu.push(pi);while(!ptQu.empty()){pi = ptQu.front();ptQu.pop();//cout << pi.x << " " <<pi.y<<endl;if(pi.x == n) {flag = 1;return;} //遍歷到了最底下,說明連通for(int i = 0; i < 4; i++){int xx = pi.x + stpX[i];int yy = pi.y + stpY[i];if(Date[xx][yy] == 0 && !visited[xx][yy]){visited[xx][yy] = 1;struct Point temp;temp.x = xx, temp.y = yy;ptQu.push(temp);}}}} }int isOk(int mid) {memcpy(Date, Gra, sizeof(Gra));for(int i = 1; i <= mid; i++)Date[ pt[i].x ][ pt[i].y ] = 1;flag = 0;BFS();//cout << mid << endl;if(flag) return 0;return 1; }int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n, &m); memset(Gra, -1, sizeof(Gra));memset(&pt, 0, sizeof(Point)); for(int i = 1; i <= n; i++ )for(int j = 1; j <= m; j++) scanf("%1d",&Gra[i][j]);int Q; scanf("%d",&Q); for(int i = 1; i <= Q; i++){int xx, yy;scanf("%d%d", &xx, &yy);pt[i].x = xx + 1;pt[i].y = yy + 1;}int lo =0;int hi = Q;while(lo <= hi)//二分求解{int mid = (lo + hi) >> 1;if(isOk(mid)) hi = mid - 1;else lo = mid + 1;//printf("%d %d\n",lo, hi); }if(hi == Q)printf("-1\n");else printf("%d\n", lo);} return 0; }
?