题意: 有一种游戏,共有三个piece(不妨称为棋子),棋盘是由N个点构成的完全图,边有颜色。每次可以移动一个棋子,移动时必须满足棋子走过的边的颜色和其他两个棋子之间的连边的颜色一致。求把三个棋子移到同一个顶点的最少次数。
这道题是一个很简单的BFS,但为何一直TLE。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 55;
struct node
{
int pos[4];
int move;
};
int n,p1,p2,p3;
char map[maxn][maxn];
bool vis[maxn][maxn][maxn];
int bfs()
{
queue<node> q;
node cur,nxt;
cur.move = 0;
cur.pos[1] = p1; cur.pos[2] = p2; cur.pos[3] = p3;
q.push(cur);
while(!q.empty()){
cur = q.front();
q.pop();
if(cur.pos[1] == cur.pos[2] && cur.pos[2] == cur.pos[3]) return cur.move;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= n; j++){
nxt.pos[1] = cur.pos[1]; nxt.pos[2] = cur.pos[2]; nxt.pos[3] = cur.pos[3];
if(i == 1 && map[cur.pos[1]][j] == map[cur.pos[2]][cur.pos[3]]){
if(vis[j][cur.pos[2]][cur.pos[3]] == true) continue;
vis[j][cur.pos[2]][cur.pos[3]] == true;
cur.pos[1] = j;
nxt.move = cur.move + 1;
q.push(nxt);
}
else if(i == 2 && map[cur.pos[2]][j] == map[cur.pos[1]][cur.pos[3]]){
if(vis[cur.pos[1]][j][cur.pos[3]] == true) continue;
vis[cur.pos[1]][j][cur.pos[3]] = true;
cur.pos[2] = j;
nxt.move = cur.move + 1;
q.push(nxt);
}
else if(i == 3 && map[cur.pos[3]][j] == map[cur.pos[1]][cur.pos[2]]){
if(vis[cur.pos[1]][cur.pos[2]][j] == true) continue;
vis[cur.pos[1]][cur.pos[2]][j] = true;
cur.pos[3] = j;
nxt.move = cur.move + 1;
q.push(nxt);
}
}
}
return -1;
}
int main()
{
while(scanf("%d",&n) != EOF && n){
scanf("%d%d%d",&p1,&p2,&p3);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
getchar();
scanf("%c",&map[i][j]);
}
}
memset(vis,false,sizeof(vis));
int ans = bfs();
if(ans == -1) printf("impossible\n");
else printf("%d\n",ans);
}
return 0;
}