题目大意:Freddy Frog暗恋Fiona Frog,在他们之间有n快石头,告诉你这n快石头的坐标,第一快为Freddy Frog的坐标,第n块为Finoa Frog的坐标,Freddy可以借助石头经过任何路径到达Fiona那里,问他最小的弹跳距离是多少(即由Freddy去Fiona的最短路径中的最长边)。

 

思路:许多人是用Dijkstra做的,其实我个人认为这一道题作者的原意还是用Prim算法的变形。应用它的贪心去更新最长的边。由于输出是.3f而WA了 N次。

 

CODE:

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>     //INT_MAX,整形范围内的最大整数。
#include <algorithm>
using namespace std;

#define INF 0x3f3f3f3f
const int SIZE = 1010;


double w[SIZE][SIZE];
double d[SIZE];
int v[SIZE];
int n;

struct node
{
    double x, y;
}a[SIZE];


double fun(const node a, const node b)
{
    return sqrt((b.y - a.y) * (b.y - a.y) + (b.x - a.x) * (b.x - a.x));
}


double Prim(int src, int e)
{
    int i, j;
    double cnt = 0;
    for(i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;
    for(i = 1; i <= n; i++)
    {
        int x;
        double m = INF;
        for(int y = 1; y <= n; y++) if(!v[y] && m > d[y]) m = d[x=y];
        v[x] = 1;
        cnt = max(cnt, m);      //记录最大值 
        if(x == e || m == INF) break;
        for(int y = 1; y <= n; y++) d[y] = min(d[y], w[x][y]); //路径更新 
    }
    return cnt;
}


void init()
{
    memset(v, 0sizeof(v));
    memset(d, 0sizeof(d));
    memset(a, 0sizeof(a));
    for(int i = 1; i <= SIZE; i++)
        for(int j = 1; j <= SIZE; j++)
            w[i][j] = INF;
}



int main()
{
    int i, j;
    int times = 0;
    while(~scanf("%d", &n), n)
    {
        init();
        for(i = 1; i <= n; i++)
        {
            scanf("%lf%lf", &a[i].x, &a[i].y);
        }
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= n; j++)
            {
                if(i == j) continue;
                w[i][j] = fun(a[i], a[j]);
            }
        }
        printf("Scenario #%d\n", ++times);
        printf("Frog Distance = ");
        double ans = Prim(12);
        printf("%.3f\n\n", ans);       //必须用.3f,用.3lf WA N次。 
    }
    return 0;
}

 

posted on 2012-09-04 13:49  有间博客  阅读(159)  评论(0编辑  收藏  举报