标签:
题意:就是选两个点出发,只能走草坪,看能不能走完所有的草坪
分析:由于数据范围很小,所有枚举这两个点,事先将所有的草坪点存起来,然后任选两个点走,(两个点可以是同一个点)
然后BFS就行了
注:无解的情况很好做,事先深搜判连通块的个数就好,大于2就无解(代码比较烂)
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> #include<map> #include<queue> #include<stdlib.h> #include<string> #include<set> using namespace std; typedef long long LL; const int maxn=12; const int INF=0x3f3f3f3f; int n,m; struct Point { int x,y; } o,t,a[105]; int mp[maxn][maxn],p,h; int bel[maxn][maxn]; char s[maxn][maxn]; int dx[4]= {0,0,-1,1}; int dy[4]= {-1,1,0,0}; void dfs(int x,int y) { bel[x][y]=p; for(int i=0; i<4; ++i) { int e=x+dx[i]; int r=y+dy[i]; if(e<1||e>n||r<1||r>m)continue; if(s[e][r]==‘.‘||bel[e][r])continue; dfs(e,r); } } queue<Point>q; int bfs() { int ans=0; h=q.size(); while(!q.empty()) { o=q.front(); q.pop(); for(int i=0; i<4; ++i) { t.x=o.x+dx[i]; t.y=o.y+dy[i]; if(t.x<1||t.x>n||t.y<1||t.y>m)continue; if(s[t.x][t.y]==‘.‘||mp[t.x][t.y]!=-1)continue; mp[t.x][t.y]=mp[o.x][o.y]+1; ans=max(ans,mp[t.x][t.y]); h++; q.push(t); } } return ans; } int main() { int T,cas=0; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(bel,0,sizeof(bel)); p=0; for(int i=1; i<=n; ++i) scanf("%s",s[i]+1); int cnt=0,ans=INF; for(int i=1; i<=n; ++i) for(int j=1; j<=m; ++j) if(s[i][j]==‘#‘) { if(!bel[i][j])++p,dfs(i,j); a[cnt].x=i,a[cnt++].y=j; } printf("Case %d: ",++cas); if(p>2) { printf("-1\n"); continue; } bool flag=0; for(int i=0; i<cnt; ++i) { for(int j=0; j<cnt; ++j) { if(p==2&&bel[a[i].x][a[i].y]==bel[a[j].x][a[j].y]) continue; h=0; memset(mp,-1,sizeof(mp)); mp[a[i].x][a[i].y]=mp[a[j].x][a[j].y]=0; q.push(a[i]); if(i!=j)q.push(a[j]); int res=bfs(); if(h==cnt)ans=min(ans,res); } } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/shuguangzw/p/5166446.html