hdu4528,带回路的广度搜索???

http://acm.hdu.edu.cn/showproblem.php?pid=4528

果断通不过这凶残的数据啊,居然还可以往回走

 

1
30 31 95
S..............................
..X............................
...X...........................
....X..........................
.....X.........................
......X........................
.......X.......................
........X......................
.........X.....................
..........X....................
...........X...................
............X..................
.............X.................
..............X................
...............X...............
................X..............
.................X.............
..................X............
...................X...........
....................X..........
.....................X.........
......................X........
.......................X.......
........................X......
.........................X.....
..........................X....
...........................X...
............................X..
.............................XE
..............................D
wrong code:
#include <iostream>
#include "stdio.h"
#include "queue.h"
#include "memory.h"
char map[105][105];			//定义图的大小
int vit[105][105];			//图结点访问的判断 
int fangxiang[4][2]={1,0,-1,0,0,1,0,-1};		//四个方向 
struct point
{
	int x;
	int y;
	int step;
	int seesum;
};
queue <point> q;		//定义队列 
int bgx,bgy;
int flag,canseesum;		//能够看到的人数和flag标记是否能看到人
int n,m,t;				//行,列,限制步数 
int cango(int x,int y)		//判断是否是有效可走点 
{
	if(x>=1&&x<=n&&y>=1&&y<=m&&!vit[x][y]&&map[x][y]=='.')
	{
		return 1;
	}
	return 0;
}
int cansee(int x,int y)			//在当前位置上是否能看到人 PS:核心语句 
{
	int i,j;
	int sum=0;
	for(i=y-1;i>=1;i--)	//左看 ,行不变列变 
	{
		if(map[x][i]=='X')	//碰到障碍 
		{
			break;
		}else if(map[x][i]=='D'||map[x][i]=='E')	//能看到大明、二明中的一个 
		{
			map[x][i]='X';
			sum+=1;
			break;
		}
	}
	for(i=y+1;i<=m;i++)	//右看 
	{
		if(map[x][i]=='X')	//碰到障碍 
		{
			break;
		}else if(map[x][i]=='D'||map[x][i]=='E')	//能看到大明、二明中的一个 
		{
			map[x][i]='X';
			sum+=1;
			break;
		}
	}
	for(j=x+1;j<=n;j++)	//下看 		//列不变行变 
	{
		if(map[j][y]=='X')	//碰到障碍 
		{
			break;
		}else if(map[j][y]=='D'||map[j][y]=='E')	//能看到大明、二明中的一个 
		{
			map[j][y]='X';
			sum+=1;
			break;
		}
	}
	for(j=x-1;j>=1;j--)	//上看 
	{
		if(map[j][y]=='X')	//碰到障碍 
		{
			break;
		}else if(map[j][y]=='D'||map[j][y]=='E')	//能看到大明、二明中的一个 
		{
			map[j][y]='X';
			sum+=1;
			break;
		}
	}
	return sum;
} 
//------------------------------------
int bfs(void)		//广度优先搜索开始 
{
	while(!q.empty())
	{
		point now;
		now=q.front();
		q.pop();
		if(now.step<=t&&now.seesum==2)	//人数找全,并且走的步数没有超出限制 
		{
			flag=1;
			return now.step;		//返回最小步数 
		}
		if(now.step>t)			//剪枝 
		{
			return -1;
		}
		int newx,newy;
		int i;
		for(i=0;i<4;i++)
		{
			newx=now.x+fangxiang[i][0];
			newy=now.y+fangxiang[i][1];
			if(cango(newx,newy))
			{
				vit[newx][newy]=1;
				int step=now.step+1;
				point newpoint;
				newpoint.x=newx;
				newpoint.y=newy;
				newpoint.step=step;
				newpoint.seesum=now.seesum+cansee(newx,newy);
				q.push(newpoint);
			}
			
		}
		
	}
	
}

using namespace std;
int main(int argc, char *argv[])
{
	int test;
	scanf("%d",&test);	//测试数据 
	int i;
	for(i=1;i<=test;i++)
	{
		memset(vit,0,sizeof(vit));
		while(!q.empty())		//队列清空 
		{
			q.pop();
		}
		scanf("%d%d%d",&n,&m,&t);	//行,列,次数
	 	int i2,j2;
	 	for(i2=1;i2<=n;i2++)
	 	{
	 		for(j2=1;j2<=m;j2++)
	 		{
		 		cin>>map[i2][j2];	//输入图的信息 
		 		if(map[i2][j2]=='S')	//确定小明位置 
		 		{
		 			bgx=i2;
		 			bgy=j2;
		 		}
		 	}
	 	}
	 	//------------------------------
	 	point start;
	 	start.x=bgx;
	 	start.y=bgy;
	 	start.step=0;
	 	vit[bgx][bgy]=1;
	 	start.seesum=cansee(bgx,bgy);
	 	q.push(start);		//开始结点放入队列
		flag=0;
		int ministep=-1;
		//--------------------------------
	 	ministep=bfs();	//开始广搜
		if(flag==0)
		{
			printf("-1\n");
		}else
		{
			printf("%d\n",ministep);
		}
	 	
	}
	return 0;
}

 

你可能感兴趣的:(hdu4528,带回路的广度搜索???)