POJ - 2252 Frogger(Dijkstra变形题)

题意:

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

两个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\n",cases);
		printf("Frog Distance = %.3lf\n\n",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\n",cases);
		printf("Frog Distance = %.3lf\n\n",dist[2]);
	}
}
时间: 2025-01-01 10:23:07

POJ - 2252 Frogger(Dijkstra变形题)的相关文章

POJ - 1511 Invitation Cards(Dijkstra变形题)

题意: 给定一个有向图,求从源点到其他各点的往返最短路径和.且这个图有一个性质:任何一个环都会经过源点. 图中的节点个数范围:0-100w; 分析: 我们先可以利用Dijkstra算法求解从源点到其余各点的最短距离,这样工作就完成了一半了. 那么如何求解从各点到源点的最短路呢? 1. 我们可以循环n-1次,每次计算点i到其余各点的最短路,从中取出i到源点的最短路,这样我们就可以其余各点到源点的最短路. 显然上述方法中存在大量冗余,显然针对题目的取值范围:0~100w,必定会超时的.如果你不信,可

poj 2253 Frogger [dijkstra]

传送门:http://poj.org/problem?id=2253 Frogger Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists

Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger

/* 好久没有做有关图论的题了,复习一下. --------------------------------------------------------- 任意两点间的最短路(Floyd-Warshall算法) 动态规划: dp[k][i][j] := 节点i可以通过编号1,2...k的节点到达j节点的最短路径. 使用1,2...k的节点,可以分为以下两种情况来讨论: (1)i到j的最短路正好经过节点k一次 dp[k-1][i][k] + dp[k-1][k][j] (2)i到j的最短路完全

poj 2253 Frogger (dijkstra最短路)

题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25773   Accepted: 8374 Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on an

poj 2253 Frogger (最长路中的最短路)

链接:poj 2253 题意:给出青蛙A,B和若干石头的坐标,现青蛙A想到青蛙B那,A可通过任意石头到达B, 问从A到B多条路径中的最长边中的最短距离 分析:这题是最短路的变形,以前求的是路径总长的最小值,而此题是通路中最长边的最小值,每条边的权值可以通过坐标算出,因为是单源起点,直接用SPFA算法或dijkstra算法就可以了 SPFA 16MS #include<cstdio> #include<queue> #include<cmath> #include<

POJ 2253 Frogger

题意:一只青蛙找到另外一只青蛙,不过可以通过其它的石头跳到目标青蛙的位置去,其中,输入数据的时候第一组数据是第一只青蛙的位置,第二组是目标青蛙的位置,其它的为石头的位置 思路:dijkstra算法的一种小小的变形,做法还是一样的 Tips:POJ上的双精度浮点型输出竟然是%f输出害的我一直错,或者是编译错误,恼啊! AC代码: #include<cstdio> #include<cmath> #include<algorithm> using namespace std

Heavy Transportation POJ 1797 最短路变形

Heavy Transportation POJ 1797 最短路变形 题意 原题链接 题意大体就是说在一个地图上,有n个城市,编号从1 2 3 ... n,m条路,每条路都有相应的承重能力,然后让你求从编号为1的城市到编号为n的城市的路线中,最大能经过多重的车. 解题思路 这个题可以使用最短路的思路,不过转移方程变了\(dis[j]=max(dis[j], min(dis[u], e[u][j]))\).这里dis[j]表示从标号为1的点到达编号为j的点的路径中,最小的承重能力,就像短板效应样

[2016-04-02][POJ][2253][Frogger]

时间:2016-04-02 17:55:33 星期六 题目编号:[2016-04-02][POJ][2253][Frogger] 题目大意:给定n个点的坐标,问从起点到终点的所有路径中,最大边的最小值是多少,即每一步至少是多少才能走到终点 分析: 方法1: 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值, 最大边的最小值:u->v d[v] = min(d[i],m

poj 2253 Frogger 解题报告

题目链接:http://poj.org/problem?id=2253 题目意思:找出从Freddy's stone  到  Fiona's stone  最短路中的最长路. 很拗口是吧,举个例子.对于 i 到 j 的一条路径,如果有一个点k, i 到 k 的距离 && k 到 j 的距离都小于 i 到 j 的距离,那么就用这两条中较大的一条来更新 i 到 j 的距离 .每两点之间都这样求出路径.最后输出 1 到 2 的距离(1:Freddy's stone   2:Fiona's sto