Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 27020 | Accepted: 8797 |
Description
Input
Output
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
Source
题意:有一条小河,河中有青蛙a和青蛙b。青蛙a呆在石头1上,青蛙b呆在石头2上,已知河中总共有n块石头,编号为1~n,已知所有石头的坐标。现在青蛙a想去找青蛙b玩,求青蛙a所需的最小跳跃距离。
解析:这个题意很简单,我们需要先预处理一下数据,建成一个无向图,然后就是dijkstra算法了,但是注意,这里求的是青蛙a所在的石头到青蛙b所在石头的路径上的最大边的值,所以松弛操作要稍微变一下形。
AC代码:
#include
#include
#include
#include
using namespace std;
#define MAXN 200 + 5
#define INF 123456789
struct Node{ int x, y; }; //顶点结构体
int V; //顶点数
Node node[MAXN];
double w[MAXN][MAXN], dis[MAXN]; //w:无向图的邻接矩阵,dis:最短路径
int vis[MAXN]; //访问数组
double dist(Node a, Node b){ //a,b两点之间的距离
return sqrt((double)((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y))); //注意一定要把sqrt()函数的参数强转成double类型,否则会CE
}
void dijkstra(){
memset(vis, 0, sizeof(vis)); //预处理
for(int i=1; i<=V; i++) dis[i] = (i==1) ? 0 : INF;
for(int i=1; i<=V; i++){ //dijkstra
int x, m = INF;
for(int y=1; y<=V; y++)
if(!vis[y] && dis[y] <= m){
x = y;
m = dis[x];
}
vis[x] = 1;
for(int y=1; y<=V ;y++) dis[y] = min(dis[y], max(dis[x], w[x][y])); //变形之后的松弛操作
}
}
int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif // sxk
int t = 0;
while(scanf("%d", &V)!=EOF && V){
for(int i=1; i<=V; i++) scanf("%d%d", &node[i].x, &node[i].y);
for(int i=1; i<=V; i++) //处理数据,建无向图
for(int j=i; j<=V; j++)
w[i][j] = w[j][i] = dist(node[i], node[j]);
dijkstra(); //处理
if(t) printf("\n"); //每个样例之间有空一行,但是最后一个样例后面没有!!!
printf("Scenario #%d\nFrog Distance = %.3lf\n", ++t, dis[2]);
}
return 0;
}
小编福利:要是想进一步了解sqrt()的RE原因的话,请点击:Compile Error 之 sqrt() 调用 ^_^