经典TSP问题先广搜求所有"dirty“点之前的距离,然后再DFS寻找所有组合(穷举法),最后取最短即为所求
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define MAXN 30
struct cnode
{
int x;
int y;
int MapToPoint;// the index of point
char ch;
}node[MAXN][MAXN];
struct cpoint
{
int x;
int y;
}point[MAXN];
int dir[][2] = {{-1,0},{0,-1},{0,1},{1,0}};
bool visit[MAXN][MAXN];
int step[MAXN][MAXN];//the distance between two point
int ans;
int SumStep[MAXN][MAXN];//note the distance of all the points from the start point in the BFS
void bfs(cpoint p,int INDEX)
{
queue<cpoint> qu;
qu.push(p);
cpoint current;
cpoint jump;
int i;
while(!qu.empty())
{
current = qu.front();
qu.pop();
for(i = 0;i < 4;i++)
{
jump.x = current.x + dir[i][0];
jump.y = current.y + dir[i][1];
if(node[jump.x][jump.y].x == -1)
{
continue;
}
if(visit[jump.x][jump.y] == false)
{
visit[jump.x][jump.y] = true;
//cout<<"no"<<endl;
if(node[jump.x][jump.y].ch != 'x')
{
if(node[jump.x][jump.y].ch == '*')
{
step[INDEX][ node[jump.x][jump.y].MapToPoint ] = SumStep[current.x][current.y] + 1;
step[ node[jump.x][jump.y].MapToPoint ][INDEX] = step[INDEX][ node[jump.x][jump.y].MapToPoint ];
}
SumStep[jump.x][jump.y] = SumStep[current.x][current.y] + 1;
qu.push(jump);
}
}
}
}
}
bool DFSVisit[MAXN];
void dfs(int sx,int sy,int INDEX,int sub,int dis,int depth)
{
if(dis > ans)
{
return;
}
int i;
depth++;
if(depth == sub && dis < ans)
{
ans = dis;
return;
}
for(i = 0;i < sub;i++)
{
if(DFSVisit[i] == false)
{
DFSVisit[i] = true;
dfs(point[i].x,point[i].y,i,sub,dis + step[INDEX][i],depth);
DFSVisit[i] = false;
}
}
}
int main()
{
int n,m;
int i;
int j;
int sx;
int sy;
int sub;
int INDEX;
while(scanf("%d %d",&m,&n) != EOF)
{
if(m == 0 && n== 0)
{
break;
}
sub = 0;
memset(node,255,sizeof(node));
for(i = 1;i <= n;i++)
{
getchar();
for(j = 1;j <= m;j++)
{
node[i][j].x = i;
node[i][j].y = j;
scanf("%c",&node[i][j].ch);
if(node[i][j].ch == '*')
{
point[sub].x = i;
point[sub].y = j;
node[i][j].MapToPoint = sub;
sub++;
}
else if(node[i][j].ch == 'o')
{
sx = i;
sy = j;
INDEX = sub;
point[sub].x = i;
node[i][j].MapToPoint = sub;
point[sub++].y = j;
}
}
}
memset(step,0,sizeof(step));
for(i = 0; i < sub;i++)
{
memset(SumStep,0,sizeof(SumStep));
memset(visit,false,sizeof(visit));
visit[point[i].x][point[i].y] = true;
bfs(point[i],i);
}
bool note = false;
for(i = 0;i < sub;i++)//if there is dity point that we can't reach ,the printf -1
{
for(j = 0;j < sub;j++)
{
if(i != j && step[i][j] == 0)
{
note = true;
printf("-1\n");
break;
}
}
if(note == true)
{
break;
}
}
if(note == true)
{
continue;
}
ans = 1e9;
memset(DFSVisit,false,sizeof(DFSVisit));
DFSVisit[INDEX] = true;
dfs(sx,sy,INDEX,sub,0,0);
if(ans == 0 && sub >= 2)
{
printf("-1\n");
}
else if(ans == 1e9)
{
printf("0\n");
}
else
{
printf("%d\n",ans);
}
}
return 0;
}