FZU 2150 Fire Game ([kuangbin带你飞]专题一 简单搜索)
题目连接:题目
题目大意:就是你又两把火,去烧草场的草,火只能上下左右烧,问烧完的时间,如果不能烧完,则输出-1;
解题思路:这个题算是第一次接触到双向广搜把,我觉得是双向广搜,,,,,,,,,,
说题把,找出两个点就去烧,然后不管是一个草堆还是多个草堆,记录每次烧的个数如果tot等于草堆总数,则是成功,否则不能烧完,并且在烧完的时候记录时间,然后维持这个时间的最小值
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<queue> using namespace std; const int maxn = 10+5; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; string s[maxn]; int n,m; int sz=0; bool vis[maxn][maxn]; struct node{ int x;int y;int t; node(){}; node(int xx,int yy,int tt):x(xx),y(yy),t(tt){}; }; struct Togo{ int x;int y; }togo[200]; int bfs(int u,int v,int k){ int tot=0; queue<node> Q; while(!Q.empty()) Q.pop(); node a; a.x=togo[u].x; a.y=togo[u].y; a.t=k; vis[a.x][a.y]=1; //标记起点 Q.push(a); node b; b.x=togo[v].x; b.y=togo[v].y; b.t=k; vis[b.x][b.y]=1; //标记起点 Q.push(b); while(!Q.empty()){ node A=Q.front(); Q.pop(); tot++; if(tot==sz) return A.t; for(int i=0;i<4;i++){ int nx=A.x+dir[i][0]; int ny=A.y+dir[i][1]; if(nx <0 || ny < 0 || nx >=n || ny >= m || s[nx][ny]=='.' || vis[nx][ny]) continue; Q.push(node(nx,ny,A.t+1)); vis[nx][ny]=1; } } return 1e9+5; } int main(int argc, char const *argv[]) { int t; scanf("%d",&t); for(int pp=1;pp<=t;pp++){ sz=0; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ cin>>s[i]; for(int j=0;j<m;j++) { if(s[i][j]=='#'){ //记录所有的草的个数 togo[sz].x=i; togo[sz].y=j; sz++; } } } int ans = 1e9+5; int c=ans; for(int i=0;i<sz;i++){ for(int j=i;j<sz;j++){ memset(vis,0,sizeof(vis)); //去烧所有的草堆不能重复 ans=min(ans,bfs(i,j,0)); } } printf("Case %d: %d\n",pp,ans==c?-1:ans); } return 0; }