首页 > 代码库 > {POJ}{3897}{Maze Stretching}{二分答案+BFS}

{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}{3897}{Maze Stretching}{二分答案+BFS}