POJ 2688 BFS+汉密尔顿路+乱优化

本文介绍了一种用于解决迷宫中机器人寻找清理脏点最短路径的问题。通过使用广度优先搜索(BFS)来构建图,并采用深度优先搜索(DFS)来求解最小代价路径。该算法能够有效地处理复杂的迷宫环境。
//Result:wizmann	2688	Accepted	896K	375MS	G++	3326B	2012-07-10 13:52:30
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bitset>
#include <queue>
#include <deque>

using namespace std;

#define print(x) cout<<x<<endl
#define input(x) cin>>x
#define SIZE 24
#define DIRTY 11
#define INF 1<<30

const int mx[]={1,0,-1,0};
const int my[]={0,1,0,-1};

struct point
{
	int x,y;
	point(){}
	point(int i_x,int i_y)
	{
		x=i_x;y=i_y;
	}
	inline void move(int dir)
	{
		x+=mx[dir];
		y+=my[dir];
	}
};

struct node
{
	int next,cost;
	node(){}
	node(int i_next,int i_cost)
	{
		next=i_next;cost=i_cost;
	}
	friend bool operator < (const node& a,const node& b)
	{
		return a.cost<b.cost;
	}
};


int r,c;
char maze[SIZE][SIZE];
point robot;
int ind;
deque<point> dirty;
vector<node> g[DIRTY];
int hash[SIZE][SIZE];

struct bnode
{
	point pos;int step;
	bnode(){}
	bnode(const point& ip,int i_s)
	{
		pos=ip;step=i_s;
	}
};

bool inMap(const point& p)
{
	if(p.y>=0 && p.y<r && p.x>=0 && p.x<c)
	{
		if(maze[p.y][p.x]!='x') return true;
		else return false;
	}
	return false;
}

void bfs(const point& start)
{
	for(int i=0;i<SIZE;i++) fill(hash[i],hash[i]+SIZE,INF);
	queue<bnode> q;
	q.push(bnode(start,0));
	while(!q.empty())
	{
		bnode now=q.front();
		q.pop();

		point p=now.pos;
		int step=now.step;

		if(hash[p.y][p.x]<=step) continue;
		else hash[p.y][p.x]=step;

		for(int i=0;i<4;i++)
		{
			point next=p;
			next.move(i);
			if(inMap(next)) q.push(bnode(next,step+1));
		}
	}
}

int makeG()
{
	memset(g,0,sizeof(g));
	for(int i=0;i<(int)dirty.size();i++)
	{
		bfs(dirty[i]);
		for(int j=0;j<(int)dirty.size();j++)
		{
			point next=dirty[j];
			g[i].push_back(node(j,hash[next.y][next.x]));
			if(hash[next.y][next.x]==INF) return -1;
		}
		sort(g[i].begin(),g[i].end());
	}
	return 0;
}

int visit[1<<DIRTY][DIRTY];
int end;

int dfs(int pos=0,int dis=0,int status=0)
{
	//print(pos<<' '<<status<<' '<<dis);
	int now_status=status|(1<<pos);
	if(visit[now_status][pos]<=dis) return INF;
	else visit[now_status][pos]=dis;
	
	if(now_status==end) return dis;

	int ans=INF;
	for(int i=0;i<(int)g[pos].size();i++)
	{
		int next=g[pos][i].next;
		int cost=g[pos][i].cost;
		ans=min(dfs(next,dis+cost,now_status),ans);
	}

	return ans;
}

int main()
{
	while(scanf("%d%d",&c,&r)!=EOF && r+c)
	{
		ind=1;
		for(int i=0;i<(1<<DIRTY);i++)
		{
			for(int j=0;j<DIRTY;j++) visit[i][j]=INF;
		}
		dirty.clear();
		for(int i=0;i<r;i++)
		{
			scanf("%s",maze[i]);
			for(int j=0;maze[i][j];j++)
			{
				if(maze[i][j]=='o')
				{
					robot=point(j,i);
					maze[i][j]='0';
				}
				else if(maze[i][j]=='*')
				{
					maze[i][j]='0'+ind++;
					dirty.push_back(point(j,i));
				}
			}
		}
		dirty.push_front(robot);
		end=(1<<ind)-1;
		//print(end);
		int cb=makeG();
		if(cb==-1)
		{
			print(-1);
			continue;
		}
		/*
		for(int i=0;i<r;i++)
		{
			for(int j=0;j<c;j++)
			{
				printf("%c",maze[i][j]);
			}
			puts("");
		}
		
		for(int i=0;i<ind;i++)
		{
			for(int j=0;j<(int)g[i].size();j++)
			{
				printf("(%d,%d) ",g[i][j].next,g[i][j].cost);
			}
			puts("");
		}
		*/
		int ans=dfs();
		printf("%d\n",(ans<INF?ans:-1));
	}
	return 0;
}

  

转载于:https://www.cnblogs.com/Wizmann/archive/2012/07/10/2584656.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值