• POJ


    题意:

          题目撰写者的英语真是艰难晦涩,看了别人题解,才知道这题题意。

          两个forger 一个froger 要蹦到另外一个froger处,他们的最短距离是这样定义的 :

         The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range

         over all possible paths between the two stones. 

         即为 :两个石头之间的frog distance就是在这两个石头之间的所有路径中最大跳(necessary jump range)最小的。 (以上引自aowarmen's blog)

    题目要我们求解的frog distance和dijksta算法中的最短路径距离不是同一个概念。

    分析:

    理解了题意之后,我们把Dijsktra中的松弛条件改成:

    dist[i] = max( dist[u],edge[u][i])  //u为某一中间节点,dist[i]表示源点到结点i的距离  (以上摘自Eucalyptus

    同时,我们可以优化距离的开根号运算,两点之间的距离定义改成:欧几里德距离的平方和。

    这样一来,我们只需要对结果开根号即可,节省中间的运算时间。

    提交时请不要用g++,要用c++编译器,同样的代码,我用G++提交时总是WA

    代码:

    优先队列实现的Dijkstra模板,只要修改对应的松弛条件即可。

    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #include<queue>
    #include<cmath>
    #include<vector>
    using namespace std;
    #define maxn 201
    #define inf 0x3f3f3f3f
    #define eps 0.0001
    typedef pair<double,int> P;
    double max(double a,double b){
    	return (a>b?a:b);
    }
    struct points {
    	int x, y;
    	points(int xi,int yi){ x=xi,y=yi;}
    	points(){x=0,y=0;}
    };
    
    points nodes[maxn];
    double map[maxn][maxn];
    double dist[maxn];
    double cal_dist(points a,points b){
    	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    void init(int n){
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			map[i][j]=cal_dist(nodes[i],nodes[j]);
                map[j][i]=map[i][j];
    		}
    	}
    }
    
    void dijkstra(int s,int n){
    	priority_queue<P,vector<P>,greater<P> > Q;
    	bool visited[maxn];
    	memset(visited,0,sizeof(visited));
    	for(int i=1;i<=n;i++)
    		dist[i]=inf;
    	dist[s]=0.0;
    	Q.push(P(0.0,s));
    
    	while(!Q.empty()){
    		int v=Q.top().second;
    		Q.pop();
    		if(visited[v]) continue;
    		visited[v]=true;
    		for(int i=1;i<=n;i++){
    			double local_max=max(dist[v],map[v][i]);
    			if(dist[i]-local_max>eps){
    				dist[i]=local_max;
    				Q.push(P(local_max,i));
    			}
    		}
    	}
    }
    int main(){
    	//freopen("in.txt","r",stdin);
    	int cases=0,n;
    	while(scanf("%d",&n)!=EOF && n){
    		cases++;
    		for(int i=1;i<=n;i++)
    			scanf("%d %d",&nodes[i].x,&nodes[i].y);
    		init(n);
    		dijkstra(1,n);
    		printf("Scenario #%d
    ",cases);
    		printf("Frog Distance = %.3lf
    
    ",sqrt(dist[2]));
    	}
    }

    普通方法实现的Dijkstra算法

    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #include<queue>
    #include<cmath>
    #include<vector>
    using namespace std;
    #define maxn 210
    #define inf 0x3f3f3f3f
    typedef pair<double,int> P;
    double max(double a,double b){
    	return (a>b?a:b);
    }
    struct point {
    	double x, y;
    	point(double xi,double yi){ x=xi,y=yi;}
    	point(){x=0,y=0;}
    };
    
    point nodes[maxn];
    double map[maxn][maxn];
    double dist[maxn];
    double cal_dist(point a,point b){
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    void init(int n){
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(i==j) map[i][j]=0.0;
    			else
    				map[i][j]=cal_dist(nodes[i],nodes[j]);
    			map[j][i]=map[i][j];
    		}
    	}
    }
    
    void dijkstra(int s,int n){
    	bool visited[maxn];
    	memset(visited,0,sizeof(visited));
    	visited[s]=true;
    	for(int i=1;i<=n;i++)
    		dist[i]=map[s][i];
    	dist[s]=0.0;
    	for(int i=1;i<=n;i++){
    		double min=inf;
    		int u=0;
    		for(int j=1;j<=n;j++)
    			if(!visited[j] && dist[j]<min){
    				min=dist[j];
    				u=j;
    			}
    		visited[u]=true;
    		if(min==inf)  break;
    		for(int j=1;j<=n;j++){
    			double tmp=max(dist[u],map[u][j]);
    			if(!visited[j]&&dist[j]>tmp)
    				dist[j]=tmp;
    		}
    	}
    }
    
    int main(){
    	//freopen("in.txt","r",stdin);
    	int cases=0,n;
    	while(scanf("%d",&n)!=EOF && n){
    		cases++;
    		for(int i=1;i<=n;i++)
    			scanf("%lf %lf",&nodes[i].x,&nodes[i].y);
    		init(n);
    		dijkstra(1,n);
    		printf("Scenario #%d
    ",cases);
    		printf("Frog Distance = %.3lf
    
    ",dist[2]);
    	}
    }
  • 相关阅读:
    心慌慌
    辛苦了
    [转]家庭长寿秘方:夫妻关系之守则。
    无题
    浮躁
    [转]樱木花道9大缺点
    一票难求
    Excel录入数据,自动记录当前时间点
    Excel数据透视表基本使用
    linux下tomcat7虚拟目录配置
  • 原文地址:https://www.cnblogs.com/ZJUT-jiangnan/p/3937626.html
Copyright © 2020-2023  润新知