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.
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
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
题意:
有两只青蛙和若干块石头,现在已知这些东西的坐标,两只青蛙A坐标和青蛙B坐标是第一个和第二个坐标,现在A青蛙想要到B青蛙那里去,并且A青蛙可以借助任意石头的跳跃,而从A到B有若干通路,问从A到B的所有通路上的最大边,比如有 有两条通路 1(4)5 (3)2 代表1到5之间的边为4, 5到2之间的边为3,那么该条通路跳跃范围(两块石头之间的最大距离)为 4, 另一条通路 1(6) 4(1) 2 ,该条通路的跳跃范围为6, 两条通路的跳跃范围分别是 4 ,6,我们要求的就是最小的那一个跳跃范围,即4,
思路:最短路算法,由于数据较小,因此可以用Floyd算法,Dijkstra算法,SPFA算法。但这一题最简单的还是用Floyd算法。
Floyd算法:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //ma用来存放两个石头之间的距离 22 double ma[210][210]; 23 int main() 24 { 25 //x,y数组存放地点 26 double x[210],y[210]; 27 int n,ans=1; 28 //n为0时退出 29 while(scanf("%d",&n)&&n) 30 { 31 int a,b; 32 for(int i=1;i<=n;i++) 33 { 34 scanf("%lf %lf",&x[i],&y[i]); 35 } 36 //初始化ma数组为0,是为了保证求的是最大距离中的小距离 37 memset(ma,0,sizeof(ma)); 38 for(int i=i=1;i<=n;i++) 39 { 40 for(int j=1;j<=n;j++) 41 { 42 //录入两个石头之间的距离 43 ma[i][j]=ma[j][i]=sqrt(pow(x[i]-x[j],2.0)+pow(y[i]-y[j],2.0)); 44 } 45 } 46 //Floyd算法核心 47 for(int k=1;k<=n;k++) 48 { 49 for(int i=1;i<=n;i++) 50 { 51 for(int j=1;j<=n;j++) 52 { 53 //许多通路中最大距离中的最小距离 54 ma[i][j]=min(ma[i][j],max(ma[i][k],ma[k][j])); 55 } 56 } 57 } 58 printf("Scenario #%d\nFrog Distance = %.3lf\n\n",ans++,ma[1][2]); 59 } 60 61 }
Dijkstra算法
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //dis用来存放到1之间的距离 22 double dis[310]; 23 //ma用来存放两个石头之间的距离 24 double ma[210][210]; 25 void dijkstra(int m) 26 { 27 int i; 28 //vis数组标记已经找过的最短路 29 bool vis[1010]; 30 memset(vis,0,sizeof(vis)); 31 for(int i=1;i<=m;i++) 32 { 33 dis[i]=INF; 34 } 35 dis[1]=0; 36 for(int i=1;i<=m;i++) 37 { 38 //mi记录当前到1距离最小的值 39 double mi=INF; 40 //k表示到1距离最小的点 41 int k=1; 42 for(int j=1;j<=m;j++) 43 { 44 //当未标记这个点,并且这个点到1的距离时最小的时侯成立, 45 if(!vis[j]&&mi>dis[j]) 46 { 47 mi=dis[j]; 48 k=j; 49 } 50 } 51 //已找到1到k点的最小值,所以标记这个点 52 vis[k]=1; 53 for(int j=1;j<=m;j++) 54 { 55 //所有通路中最大距离中的最小数 56 dis[j]=min(dis[j],max(dis[k],ma[k][j])); 57 } 58 } 59 } 60 61 int main() 62 { 63 //x,y数组存放地点 64 double x[210],y[210]; 65 int n,ans=1; 66 //n为0时退出 67 while(scanf("%d",&n)&&n) 68 { 69 int a,b; 70 for(int i=1;i<=n;i++) 71 { 72 scanf("%lf %lf",&x[i],&y[i]); 73 } 74 //初始化ma数组为0,是为了保证求的是最大距离中的小距离 75 memset(ma,0,sizeof(ma)); 76 for(int i=i=1;i<=n;i++) 77 { 78 for(int j=1;j<=n;j++) 79 { 80 //录入两个石头之间的距离 81 ma[i][j]=ma[j][i]=sqrt(pow(x[i]-x[j],2.0)+pow(y[i]-y[j],2.0)); 82 } 83 } 84 dijkstra(n); 85 printf("Scenario #%d\nFrog Distance = %.3lf\n\n",ans++,dis[2]); 86 } 87 88 }
SPFA算法
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 //ma用来存放两个石头之间的距离 22 double ma[210][210]; 23 //dis用来存放到1之间的距离 24 double dis[310]; 25 //vis数组标记已经找过的最短路 26 bool vis[1010]; 27 28 void spfa(int m) 29 { 30 //qu用来存放需要遍历的石头 31 queue<int> qu; 32 //初始dis为最大数 33 for(int i=1;i<=m;i++) 34 { 35 dis[i]=INF; 36 } 37 //初始vis为0,表示所有点都未被记录 38 memset(vis,0,sizeof(vis)); 39 //1不需要记录 40 vis[1]=1; 41 //1到1的距离为0 42 dis[1]=0; 43 //第一个点为1,入队 44 qu.push(1); 45 //当队伍为空时退出 46 while(!qu.empty()) 47 { 48 int k=qu.front(); 49 qu.pop(); 50 //k的记录被推反,重新记录 51 vis[k]=0; 52 //遍历1到m 53 for(int i=1;i<=m;i++) 54 { 55 //如果1到k之间距离加上k到i将距离比1到i点距离小则更新dis 56 if(max(dis[k],ma[k][i])<dis[i]) 57 { 58 //更新dis[i] 59 dis[i]=max(dis[k],ma[k][i]); 60 //如果i点已被标记则不入队 61 if(!vis[i]) 62 { 63 //由于i点距离被更新,因此需要重新遍历与i连接的点,所以将i点入队,且标记i点 64 qu.push(i); 65 vis[i]=1; 66 } 67 } 68 } 69 } 70 } 71 int main() 72 { 73 //x,y数组存放地点 74 double x[210],y[210]; 75 int n,ans=1; 76 //n为0时退出 77 while(scanf("%d",&n)&&n) 78 { 79 int a,b; 80 for(int i=1;i<=n;i++) 81 { 82 scanf("%lf %lf",&x[i],&y[i]); 83 } 84 //初始化ma数组为0,是为了保证求的是最大距离中的小距离 85 memset(ma,0,sizeof(ma)); 86 for(int i=i=1;i<=n;i++) 87 { 88 for(int j=1;j<=n;j++) 89 { 90 //录入两个石头之间的距离 91 ma[i][j]=ma[j][i]=sqrt(pow(x[i]-x[j],2.0)+pow(y[i]-y[j],2.0)); 92 } 93 } 94 spfa(n); 95 printf("Scenario #%d\nFrog Distance = %.3lf\n\n",ans++,dis[2]); 96 } 97 }