POJ 2688 TSP问题

 经典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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值