題面描述
All of us love treasures, right? That's why young Vasya is heading for a Treasure Island.
Treasure Island may be represented as a rectangular table n×m which is surrounded by the ocean. Let us number rows of the field with consecutive integers from 1 to n from top to bottom and columns with consecutive integers from 1 to m from left to right. Denote the cell in r-th row and c-th column as (r,c). Some of the island cells contain impassable forests, and some cells are free and passable. Treasure is hidden in cell (n,m).
Vasya got off the ship in cell (1,1). Now he wants to reach the treasure. He is hurrying up, so he can move only from cell to the cell in next row (downwards) or next column (rightwards), i.e. from cell (x,y) he can move only to cells (x+1,y) and (x,y+1). Of course Vasya can't move through cells with impassable forests.
Evil Witch is aware of Vasya's journey and she is going to prevent him from reaching the treasure. Before Vasya's first move she is able to grow using her evil magic impassable forests in previously free cells. Witch is able to grow a forest in any number of any free cells except cells (1,1) where Vasya got off his ship and (n,m) where the treasure is hidden.
Help Evil Witch by finding out the minimum number of cells she has to turn into impassable forests so that Vasya is no longer able to reach the treasure.
輸入格式
First line of input contains two positive integers n, m (3≤n?m≤1000000), sizes of the island.
Following n lines contains strings si of length m describing the island, j-th character of string si equals "#" if cell (i,j) contains an impassable forest and "." if the cell is free and passable. Let us remind you that Vasya gets of his ship at the cell (1,1), i.e. the first cell of the first row, and he wants to reach cell (n,m), i.e. the last cell of the last row.
It's guaranteed, that cells (1,1) and (n,m) are empty.
輸出格式
Print the only integer k, which is the minimum number of cells Evil Witch has to turn into impassable forest in order to prevent Vasya from reaching the treasure.
樣例數(shù)據(jù)
樣例輸入
2 2
..
..
樣例輸出
2
題解
簡(jiǎn)單題......
事實(shí)上,考慮最大答案,就是將(1,2)和(2,1)一起堵上,或者將(n-1,m)和(n,m-1)一起堵上,因此答案最大為2。
再考慮走法。如果單純判斷是否能到達(dá)起點(diǎn)/終點(diǎn)的相鄰節(jié)點(diǎn),可能會(huì)出現(xiàn)以下情況:
input:
. . . . . # .
. . . . . # .
. . . . . # .
. . . . . . .
# # # # # # .
. . . . . . .
這時(shí)我們發(fā)現(xiàn) 起點(diǎn)和終點(diǎn)的兩個(gè)臨近節(jié)點(diǎn)都能到達(dá),而答案則是1,因此我們需要其它方案。
考慮是否有兩條通路。我們先進(jìn)行一次dfs,若沒有通路則直接輸出0。若有通路則將這條路徑堵上,并進(jìn)行第二次dfs。若第二次dfs有答案則輸出2,否則輸出1。
關(guān)于正確性,因?yàn)閐fs的特性是不碰到障礙物就不會(huì)改變移動(dòng)的方向(左手法則/右手法則),因此即使有兩個(gè)解,我們也會(huì)優(yōu)先堵上不會(huì)對(duì)另外一個(gè)答案產(chǎn)生影響的通路,可以保證正確。
#include<bits/stdc++.h>
#define int long long
#define maxn 1000
using namespace std;
inline char get(){
static char buf[30000],*p1=buf,*p2=buf;
return p1==p2 && (p2=(p1=buf)+fread(buf,1,30000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
register char c=getchar();register int f=1,_=0;
while(c>'9' || c<'0')f=(c=='-')?-1:1,c=getchar();
while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=getchar();
return _*f;
}
int n,m;
set<pair<int,int> > mp,vis;
int dfs(int x,int y){
//cout<<x<<" "<<y<<endl;
if(x==n && y==m)return 1;
if(vis.count(make_pair(x,y)))return 0;
if(mp.count(make_pair(x,y)))return 0;
if(x>n || y>m)return 0;
vis.insert(make_pair(x,y));
if(dfs(x+1,y)==1){
mp.insert(make_pair(x+1,y));
return 1;
}
if(dfs(x,y+1)==1){
mp.insert(make_pair(x,y+1));
return 1;
}
return 0;
}
signed main(){
//freopen("1.txt","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(register int i=1;i<=n;i++){
char cas;
for(register int j=1;j<=m;j++){
cin>>cas;
if(cas=='#')mp.insert(make_pair(i,j));
}
}
if(dfs(1,1)==0){
cout<<0;
return 0;
}
vis.clear();
if(dfs(1,1)==0){
cout<<1;
return 0;
}
else{
cout<<2;
return 0;
}
return 0;
}