天天看點

B - Frogger——最短路變形(floyd,spfa,Dijkstra)

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' sunscreen, he wants to avoid swimming and instead reach her by jumping.

Unfortunately Fiona's stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps.

To execute a given sequence of jumps, a frog's jump range obviously must be at least as long as the longest jump occuring in the sequence.

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.

You are given the coordinates of Freddy's stone, Fiona's stone and all other stones in the lake. Your job is to compute the frog distance between Freddy's and Fiona's stone.

Input

The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy's stone, stone #2 is Fiona's stone, the other n-2 stones are unoccupied. There's a blank line following each test case. Input is terminated by a value of zero (0) for n.

Output

For each test case, print a line saying "Scenario #x" and a line saying "Frog Distance = y" where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

Sample Input

2
0 0
3 4

3
17 4
19 4
18 5

0
           
/*基本的最短路題,考的是對最短路的了解
  不管是Floyd算法還是Dijkstra算法
  都是基于這樣一個事實:
  對于任意一條至少包含兩條邊的路徑i->j,
  一定存在一個中間點k,使的i->j的總長度等于i->k和k->j的長度之和
  對于不同的點k,i->k和k->j的長度之和可能不同,
  是以,最後還需要取一個最小值才是i->j的最短路徑
                                               ——劉汝佳《算法競賽入門經典》
   而且這個題隻需要把‘之和’改成‘求最大值’,其他的都不變 。 
*/ 
//Dijkstra算法
#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 300;
double map[maxn][maxn];
int n;
int x[maxn],y[maxn];
int visited[maxn];
double dis[maxn];
void Dijkstra(int s)
{
	memset(visited,0,sizeof(visited));
	for(int i = 1;i<=n;i++)
	    dis[i]=INF;
	dis[s]=0;
	for(int i = 1;i<=n-1;i++)
	{
		int minn=INF,k;
		for(int j = 1;j<=n;j++)
			if(!visited[j]&&minn>dis[j])
				minn=dis[k=j];
		visited[k]=1;
		for(int j = 1;j<=n;j++) 
		   dis[j]=min(dis[j],max(dis[k],map[k][j]));//根據Dijkstra的基本算法,就這裡變了。 
	}
}
int main(int argc, char** argv) {
	int cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0) break;
		printf("Scenario #%d\n",++cas);
		for(int i = 1;i<=n;i++)
		    scanf("%d %d",&x[i],&y[i]);
		for(int i = 1;i<=n;i++)//預先處理一下,把兩個點的邊的權值指派為其距離 
		    for(int j=i+1;j<=n;j++)
		        map[i][j]=map[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
		Dijkstra(1);
		printf("Frog Distance = %.3f\n\n",dis[2]);
	}
	return 0;
}
           
//Floyd算法
#include <iostream>
#include<cstring>
#include<algorithm>
#include<cstdio> 
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 300;
struct node{
	int x,y;
}p[maxn];
double map[maxn][maxn];
int n; 
void floyd()
{
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			    map[i][j]=min(map[i][j],max(map[i][k],map[k][j]));
}
int main(int argc, char** argv) {
	int cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0) break;
		memset(map,0,sizeof(map));
		for(int i = 1;i<=n;i++) 
		    scanf("%d %d",&p[i].x,&p[i].y);
		for(int i = 1;i<=n;i++)
		    for(int j = i+1;j<=n;j++)
		        map[i][j]=map[j][i]=sqrt(double(p[i].x-p[j].x)*(p[i].x-p[j].x)+double(p[i].y-p[j].y)*(p[i].y-p[j].y)); 
		floyd();
		printf("Scenario #%d\n",++cas);
		printf("Frog Distance = %.3f\n\n",map[1][2]);
	}
	return 0;
}
           
​//spfa算法 
#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 300;
double map[maxn][maxn];
int n;
int x[maxn],y[maxn];
int visited[maxn];
double dis[maxn];
void SPFA()
{
	queue<int> q;
	for(int i = 1;i<=n;i++) dis[i]=INF;
	memset(visited,0,sizeof(visited));
	dis[1]=0;
	visited[1]=1;
	q.push(1);
	while(!q.empty())
	{
		int news=q.front();q.pop();
		visited[news]=0;
		for(int j = 1;j<=n;j++){
			if(max(dis[news],map[news][j])<dis[j]){
				dis[j]=max(dis[news],map[news][j]);
				if(!visited[j]){
					q.push(j);
					visited[j]=1;
				}
			}
		}
	}
}
int main(int argc, char** argv) {
	int cas=0;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0) break;
		printf("Scenario #%d\n",++cas);
		for(int i = 1;i<=n;i++)
		    scanf("%d %d",&x[i],&y[i]);
		for(int i = 1;i<=n;i++)
		    for(int j=i+1;j<=n;j++)
		        map[i][j]=map[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
		SPFA();
		printf("Frog Distance = %.3f\n\n",dis[2]);
	}
	return 0;
}​
           

繼續閱讀