{POJ}{3897}{Maze Stretching}{二分答案+BFS}

题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据。

思路:由于是单调的,可以用二分答案,然后BFS验证。这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以。好久不写图论,WA成狗

#include <iostream>

#include <string>

#include <cstring>

#include <cstdio>

#include <algorithm>

#include <memory>

#include <cmath>

#include <bitset>

#include <queue>

#include <vector>

#include <stack>

using namespace std;

 



#define CLR(x,y) memset(x,y,sizeof(x))

#define MIN(m,v) (m)<(v)?(m):(v)

#define MAX(m,v) (m)>(v)?(m):(v)

#define ABS(x) ((x)>0?(x):-(x))

#define rep(i,x,y) for(i=x;i<y;++i)



#define SET_NODE(no,a,b,c) {no.x=a;no.y=b;no.val=c;}



const int MAXN = 200;

const double INF = 1<<30;

const double EPS = 0.000001;



int dir[4][2]={1,0,-1,0,0,1,0,-1};

int n,m;

int tag[MAXN];

char g[MAXN][MAXN];

double dist;

bool visit[MAXN][MAXN];

double dis[MAXN][MAXN];

typedef struct

{

	int x,y;

	double val;

}Node;

Node s,e,node;

bool operator < (const Node& a,const Node& b)

{

    return a.val > b.val;

}

bool check(const int& x, const int& y)

{

	if(x<0||x>=n) return false;

	if(y<0||y>=m) return false;

	if(g[x][y] == '#') return false;

	if(visit[x][y]) return false;

	return true;

}





double BFS(double len)

{

	int i,j,k;

	Node tmp;



	priority_queue<Node> q;





	q.push(s);



	CLR(visit,0);



	rep(i,0,n)

		rep(j,0,m)

			dis[i][j] = INF;



	while(!q.empty())

	{

		node = q.top();

		q.pop();

		visit[node.x][node.y] = true;



		if(node.x == e.x && node.y == e.y) 

			return node.val;



		if(check(node.x+1,node.y)){

			SET_NODE(tmp,node.x+1,node.y,node.val+len);

			if(tmp.val<dis[tmp.x][tmp.y])

			{

				dis[tmp.x][tmp.y] = tmp.val;

				q.push(tmp);

			}

		}

		if(check(node.x-1,node.y)){

			SET_NODE(tmp,node.x-1,node.y,node.val+len);

			if(tmp.val<dis[tmp.x][tmp.y])

			{

				dis[tmp.x][tmp.y] = tmp.val;

				q.push(tmp);

			}

		}

		if(check(node.x,node.y+1)){

			SET_NODE(tmp,node.x,node.y+1,node.val+1);

			if(tmp.val<dis[tmp.x][tmp.y])

			{

				dis[tmp.x][tmp.y] = tmp.val;

				q.push(tmp);

			}

		}

		if(check(node.x,node.y-1)){

			SET_NODE(tmp,node.x,node.y-1,node.val+1);

			if(tmp.val<dis[tmp.x][tmp.y])

			{

				dis[tmp.x][tmp.y] = tmp.val;

				q.push(tmp);

			}

		}

	}

	return 0;

}

void Solve()

{

	int i,j,k,t,tt;



	scanf("%d",&tt);

	rep(t,1,tt+1){

		scanf("%lf%d",&dist,&n);

		rep(i,0,n)

		{

		getchar();

			gets(&g[i][0]);

		}

		m = strlen(g[0]);

		rep(i,0,n)

			rep(j,0,m)

				if(g[i][j]=='S')

				{

					s.x = i;

					s.y = j;

				}else if (g[i][j]=='E')

				{

					e.x = i;

					e.y = j;

				}

		s.val = 0;



		double low = 0;

		double high = 10;

		double mid = (low+high)/2;

		double res = 0;

		while(ABS(low-high)>EPS)

		{

			mid = (low+high)/2;

			res = BFS(mid);

			//printf("[%f %f %f]\n",mid,res,dist);

			if(res < dist+EPS)

				low = mid ;

			else

				high = mid;

		}

		printf("Case #%d: %.3f%%\n",t,mid*100);

	}

}

int main()

{

	Solve();

	return 0;

}

 

你可能感兴趣的:(poj)