单向BFS 1150ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define FRER() freopen("in.txt","r",stdin)
#define FREW() freopen("out.txt","w",stdout)
#define go int T;cin>>T;for(int kase=0;kase<T;kase++)
#define debug cout<<"****************"<<endl
#define lowbit(x) x&(-x)
#define eps 1e-6
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
int n,m,kk,nEdge;
char g[20][20];
int d[300][300][300];
int id[20][20];
int head[300],nxt[10000],to[10000];
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
struct Node{
int a,b,c;
Node(){a=270;b=271;c=272;}
Node(int _a,int _b,int _c):a(_a),b(_b),c(_c){}
bool operator == (const Node& rhs) const {
return a == rhs.a && b == rhs.b && c == rhs.c;
}
};
void Init(){for(int i=0;i<16;i++)for(int j=0;j<16;j++)id[i][j]=16*i+j;}
bool can(int x,int y){if(0<=x&&x<n&&0<=y&&y<m&&g[x][y]!='#')return true;return false;}
void addEdge(int u,int v){to[nEdge]=v;nxt[nEdge]=head[u];head[u]=nEdge++;}
bool ok(Node u,Node v){
if(v.a==v.b||v.b==v.c||v.a==v.c) return false;
if(u.a==v.b&&u.b==v.a) return false;
if(u.a==v.c&&u.c==v.a) return false;
if(u.b==v.c&&u.c==v.b) return false;
return true;
}
int bfs(Node st,Node ed){
memset(d, -1, sizeof(d));
queue<Node>q;
d[st.a][st.b][st.c] = 0;
q.push(st);
while(!q.empty()){
Node u = q.front();q.pop();
if(u==ed) return d[u.a][u.b][u.c];
for(int i=head[u.a];~i;i=nxt[i]){
for(int j=head[u.b];~j;j=nxt[j]){
for(int k=head[u.c];~k;k=nxt[k]){
Node v = Node(to[i],to[j],to[k]);
if(ok(u,v)&&!~d[v.a][v.b][v.c]){
d[v.a][v.b][v.c] = d[u.a][u.b][u.c] + 1;
q.push(v);
}
}
}
}
}
return 0;
}
int main(){
//FRER();
//FREW();
Init();
while(~scanf("%d%d%d",&m,&n,&kk)&&m){
getchar();
Node st,ed;
nEdge = 0;memset(head, -1, sizeof(head));
for(int i=0;i<n;i++) gets(g[i]);
for(int i=0;i<300;i++) addEdge(i, i);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]=='a') st.a = id[i][j];
if(g[i][j]=='b') st.b = id[i][j];
if(g[i][j]=='c') st.c = id[i][j];
if(g[i][j]=='A') ed.a = id[i][j];
if(g[i][j]=='B') ed.b = id[i][j];
if(g[i][j]=='C') ed.c = id[i][j];
if(g[i][j]!='#'){
for(int k=0;k<4;k++){
int x = i + dx[k];
int y = j + dy[k];
if(can(x, y)) addEdge(id[i][j], id[x][y]);
}
}
}
}
cout << bfs(st,ed) << endl;
}
}
双向BFS 770ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define FRER() freopen("in.txt","r",stdin)
#define FREW() freopen("out.txt","w",stdout)
#define go int T;cin>>T;for(int kase=0;kase<T;kase++)
#define debug cout<<"****************"<<endl
#define lowbit(x) x&(-x)
#define eps 1e-6
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
int n,m,kk,nEdge;
char g[20][20];
int d[2][300][300][300];
int id[20][20];
int head[300],nxt[10000],to[10000];
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
struct Node{
int a,b,c;
Node(){a=270;b=271;c=272;}
Node(int _a,int _b,int _c):a(_a),b(_b),c(_c){}
bool operator == (const Node& rhs) const {
return a == rhs.a && b == rhs.b && c == rhs.c;
}
};
void Init(){for(int i=0;i<16;i++)for(int j=0;j<16;j++)id[i][j]=16*i+j;}
bool can(int x,int y){if(0<=x&&x<n&&0<=y&&y<m&&g[x][y]!='#')return true;return false;}
void addEdge(int u,int v){to[nEdge]=v;nxt[nEdge]=head[u];head[u]=nEdge++;}
bool ok(Node u,Node v){
if(v.a==v.b||v.b==v.c||v.a==v.c) return false;
if(u.a==v.b&&u.b==v.a) return false;
if(u.a==v.c&&u.c==v.a) return false;
if(u.b==v.c&&u.c==v.b) return false;
return true;
}
int bfs(Node st,Node ed){
memset(d, -1, sizeof(d));
queue<Node>q1;
queue<Node>q2;
q1.push(st);
q2.push(ed);
d[0][st.a][st.b][st.c] = 0;
d[1][ed.a][ed.b][ed.c] = 0;
while(!q1.empty()||!q2.empty()){
if(!q1.empty()){
Node u = q1.front();q1.pop();
for(int i=head[u.a];~i;i=nxt[i]){
for(int j=head[u.b];~j;j=nxt[j]){
for(int k=head[u.c];~k;k=nxt[k]){
Node v = Node(to[i],to[j],to[k]);
if(ok(u, v)&&!~d[0][v.a][v.b][v.c]){
d[0][v.a][v.b][v.c] = d[0][u.a][u.b][u.c] + 1;
if(d[1][v.a][v.b][v.c]!=-1) return d[0][v.a][v.b][v.c] + d[1][v.a][v.b][v.c];
q1.push(v);
}
}
}
}
}
if(!q2.empty()){
Node u = q2.front();q2.pop();
for(int i=head[u.a];~i;i=nxt[i]){
for(int j=head[u.b];~j;j=nxt[j]){
for(int k=head[u.c];~k;k=nxt[k]){
Node v = Node(to[i],to[j],to[k]);
if(ok(u, v)&&!~d[1][v.a][v.b][v.c]){
d[1][v.a][v.b][v.c] = d[1][u.a][u.b][u.c] + 1;
if(d[0][v.a][v.b][v.c]!=-1) return d[0][v.a][v.b][v.c] + d[1][v.a][v.b][v.c];
q2.push(v);
}
}
}
}
}
}
return 0;
}
int main(){
//FRER();
//FREW();
Init();
while(~scanf("%d%d%d",&m,&n,&kk)&&m){
getchar();
Node st,ed;
nEdge = 0;memset(head, -1, sizeof(head));
for(int i=0;i<n;i++) gets(g[i]);
for(int i=0;i<300;i++) addEdge(i, i);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]=='a') st.a = id[i][j];
if(g[i][j]=='b') st.b = id[i][j];
if(g[i][j]=='c') st.c = id[i][j];
if(g[i][j]=='A') ed.a = id[i][j];
if(g[i][j]=='B') ed.b = id[i][j];
if(g[i][j]=='C') ed.c = id[i][j];
if(g[i][j]!='#'){
for(int k=0;k<4;k++){
int x = i + dx[k];
int y = j + dy[k];
if(can(x, y)) addEdge(id[i][j], id[x][y]);
}
}
}
}
cout << bfs(st,ed) << endl;
}
}