• {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]
    ",mid,res,dist);
    			if(res < dist+EPS)
    				low = mid ;
    			else
    				high = mid;
    		}
    		printf("Case #%d: %.3f%%
    ",t,mid*100);
    	}
    }
    int main()
    {
    	Solve();
    	return 0;
    }
    
  • 相关阅读:
    ThinkPHP函数详解:C方法
    ThinkPHP函数详解:A方法
    php中的中文字符串长度计算以及截取
    JQ $("#form1 :input" ).length 与 $("#form1input").length有什么区别?
    php中的isset和empty的区别与认识
    谈谈ACM带来的一些东西
    HDU 4374--F(x)
    奖学金
    数字排序
    查找数字
  • 原文地址:https://www.cnblogs.com/lvpengms/p/3930290.html
Copyright © 2020-2023  润新知