解答のコード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
#define rep(k,i,n) for(ll i=k;i<n;++i)
const ll inf=1e6;
ll c0[20][20],c1[20][20][20][20];//c0は入力の値を保存、c1は開始地点を変えながらbfsをしたときそれぞれの座標のd（最短距離）を保存するための配列
ll dx[4]={0,0,1,-1},dy[4]={-1,1,0,0};//周辺を探索するときの座標変化
ll h,w;
ll bfs(ll sx,ll sy){
    if(c0[sx][sy]==-1)return 0;//開始地点が壁の時は0を返す。
    ll res=0;//最短距離の最大値の初期化
    ll d=0;//最短距離の値の初期化
    c1[sx][sy][sx][sy]=d;//スタート地点の初期化
    queue<P> que;//未探索の次に探索する座標を保存させるためのqueue
    que.push(P(sx,sy));//スタート地点の座標をqueueに保存
    while(!que.empty()){//bfsが終わったらqueueにはいる座標はなくなるので、queueになくなるまでループを繰り返す
        P p=que.front();que.pop();//queueを取り出す。
        rep(0,i,4){
            ll nx=p.first+dx[i],ny=p.second+dy[i];//多分now_xの略、今現在見ている座標を意味する。
            if(0<=nx && h>nx && 0<=ny && w>ny){//範囲内の座標の条件
                ll d=c1[sx][sy][nx][ny];
                if(d==inf){//未探索の条件
                    que.push(P(nx,ny));//次の探索範囲に追加
                    c1[sx][sy][nx][ny]=c1[sx][sy][p.first][p.second]+1;//最短距離をc1に入れる
                    res=max(c1[sx][sy][nx][ny],res);//ここまでの最大値を入力
                }
            }
        }
    }
    return res;
}
int main(void){
    cin>>h>>w;//座標の大きさの入力
    rep(0,i,h){
        string s0;
        cin>>s0;
        rep(0,j,w){
            string s1=s0.substr(j,1);//座標ごとの文字をs1に入力
            if(s1=="#"){
                c0[i][j]=-1;//壁があるとき、c0に-1を入力
            }else{
                c0[i][j]=inf;//未探索の印にc0にinfを入力
            }
        }
    }
    ll ans=0;//答えの初期化
    rep(0,i0,h){
        rep(0,j0,w){
            rep(0,i1,h){
                rep(0,j1,w){
                    c1[i0][j0][i1][j1]=c0[i1][j1];//c0によりc1を初期化、(i0,j0)は開始地点。
                }
            }
            ans=max(bfs(i0,j0),ans);//それぞれの開始地点においてbfsをし、最大値をとる。
        }
    }
    cout<<ans<<endl;
}