Frogger POJ - 2253(迪杰斯特拉变形)

湖中有n块石头,编号从1到n,有两只青蛙,Bob在1号石头上,Alice在2号石头上,Bob想去看望Alice,但由于水很脏,他想避免游泳,于是跳着去找她。但是Alice的石头超出了他的跳跃范围。因此,Bob使用其他石头作为中间站,通过一系列的小跳跃到达她。两块石头之间的青蛙距离被定义为两块石头之间所有可能路径上的最小必要跳跃距离,某条路径的必要跳跃距离即这条路径中单次跳跃的最远跳跃距离。你的工作是计算Alice和Bob石头之间的青蛙距离。

Input

多实例输入
先输入一个整数n表示石头数量,当n等于0时结束。
接下来2-n+1行依次给出编号为1到n的石头的坐标xi , yi。
2 <= n <= 200
0 <= xi , yi <= 1000

Output

先输出"Scenario #x", x代表样例序号。
接下来一行输出"Frog Distance = y", y代表你得到的答案。
每个样例后输出一个空行。
(ps:wa有可能是精度问题,g++不对可以用c++尝试,都不对就是代码问题)

Sample Input

2
0 0
3 4

3
17 4
19 4
18 5

0

Sample Output

Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

这道题目,一开始看不懂是什么意思,看了网上的题解后,就是比如说两地之间有很多的通路可以选择,那么每一条通路我们也有很多的节点,那么这一条通路上各个节点之间最大距离,然后每一个通路都会有一个这个最大距离,然后输出两地之间最小的那个距离,一开始真的没有看懂。我们开始想,我们是使得每条边都是最短的,(为什么要考虑这个呢,因为还有一个题型是最大的最小边权,那个是将边都尽量大,我们这个都使得边尽量小),仔细想想这个问题,要求我们输出最小(好几条边,这个是以通路为单位)的那个最大值(一条通路里面最大边,这个是以一个通路中的边为单位),我画一个图就很清晰了:就是下面这个图的意思,画出来就很清晰了。

 然后就继续上面那个问题,我们可以看看这两个事情(一个最大,一个最小),我们可以清楚的看见侧重点,当然是那个最小值比最大值重要,所以我们都筛选最小的路径(有点最小生成树的意思,当然相反,那个最大最小的像最大生成树),解决这个主题思想后,我们就开始选择这个一条路径当中的最大值了,我们在迪杰斯特拉函数中(底下这个函数),就是在由一个中间点到最终点的时候,我们就比较到中间点和中间点到最终点的权值,取最大的那个,然后再与其他通路比较,得出那个最小的权值。就是下面这个函数所写的一样。

    for(int i=0;i<=n;i++)
		{
			double minv=inf;
			for(int j=1;j<=n;j++)
			{
				if(!vis1[j]&&minv>d[j])
				{
					pos=j;
					minv=d[j];
				}
			}
			vis1[pos]=1;
			for(int j=1;j<=n;j++)
			{
				d[j]=min(d[j],max(d[pos],maap[pos][j]));  //终点
			}
			
		}

代码:

#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<string.h>
typedef long long ll;
using namespace std;
const int maxn=500;
const double inf = 0x3f3f3f3f;
typedef struct 
{
	int x,y;
}point;
point  s[maxn];
int vis1[maxn];

int n;
int vis[maxn];
double maap[maxn][maxn];
double d[maxn];

void init()
{
	memset(vis,0,sizeof(vis));
	memset(vis1,0,sizeof(vis1));
	memset(d,0,sizeof(d));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		if(i==j)
			maap[i][j]=0;
		else
			maap[i][j]=inf;
	
}

double suan(point a,point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
	
}

int main()
{
	int kase=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
			break;
		
		init();
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&s[i].x,&s[i].y);
			vis[i]=1;
			for(int j=1;j<=n;j++)
			{
				if(vis[j]&&i!=j)
				{
					double val=suan(s[i],s[j]);
					if(maap[i][j]>val)
					{
						maap[i][j]=maap[j][i]=val;
					}
				}
			}	
		}

		for(int i=1;i<=n;i++)
			d[i]=maap[1][i];
		int pos;
		
		for(int i=0;i<=n;i++)
		{
			double minv=inf;
			for(int j=1;j<=n;j++)
			{
				if(!vis1[j]&&minv>d[j])
				{
					pos=j;
					minv=d[j];
				}
			}
			vis1[pos]=1;
			for(int j=1;j<=n;j++)
			{
				d[j]=min(d[j],max(d[pos],maap[pos][j]));
			}
			
		}
		printf("Scenario #%d\n",++kase);
		printf("Frog Distance = %.3f\n",d[2]);
		printf("\n");
			
	}
	return 0;
}

解法很精妙。优秀 ,优秀。。

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89683300