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

//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;

}

  

你可能感兴趣的:(poj)