POJ 2253 Frogger【最短路變形——路徑上最小的最大權】

連接:



Frogger
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 21206   Accepted: 6903

Description算法

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. 

Inputapp

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.

Outputide

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 Inputspa

2
0 0
3 4

3
17 4
19 4
18 5

0

Sample Outputcode

Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

Sourcethree




題意:


       給出一個無向圖,求一條1~2的路徑使得路徑上的最大邊權最小.

算法:

floyd 變形或者 Dijkstra 變形均可以

分析:

        floyd變形,將更新距離的過程改成取最大值便可.
        w[i][j] = min(w[i][j], max(w[i][k], w[k][j]))


PS:

     這道題不像其它的最短路,是求總路徑最小,而是無論總路徑,只要保證路徑上的最大邊權在全部能夠走的路徑中最小就能夠了 因此要遍歷每一條路徑了Orz 若是用 Dijkstra 寫有點像 Prim

code:

floyd:

/*
題意:給出一個無向圖,求一條1~2的路徑使得路徑上的最大邊權最小.

分析:floyd變形,將更新距離的過程改成取最大值便可.
*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;

const double DNF = 2000;
const int maxn = 210;

double w[maxn][maxn];
int n;

struct Point{
    double x,y;
}p[maxn];

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

void floyd()
{
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                w[i][j] = min(w[i][j], max(w[i][k], w[k][j])); //更新i——j路徑上最小的最大邊權
}

int main()
{
    int kcase = 0;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0) break;
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }

        for(int i = 1; i <= n; i++)
        {
            w[i][i] = 0;
            for(int j = i+1; j <= n; j++)
            {
                w[i][j] = dist(p[i],p[j]);
                w[j][i] = dist(p[i],p[j]);
            }
        }

        floyd();
        printf("Scenario #%d\n", ++kcase);
        printf("Frog Distance = %.3lf\n\n", w[1][2]);
    }
}

Dijkstra:

/*
題意:給出一個無向圖,求一條1~2的路徑使得路徑上的最大邊權最小.

分析:dijkstra變形,將更新距離的過程改成取最大值便可.
*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;

const double DNF = 2000;
const int maxn = 210;

double w[maxn][maxn];
double d[maxn];
int vis[maxn];
int n;
double ans;

struct Point{
    double x,y;
}p[maxn];

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

void Dijkstra()
{
    for(int i = 1; i <= n; i++) d[i] = DNF;
    d[1] = 0;
    memset(vis,0,sizeof(vis));

    for(int i = 1; i <= n; i++)
    {
        int x;
        double m = DNF;
        for(int y = 1; y <= n; y++) if(!vis[y] && d[y] <= m) m = d[x=y];
        vis[x] = 1;
        if(ans < d[x] && d[x]!= DNF) // ans 是這條路徑上的最大權
        {
            ans = d[x];
        }
        if(x == 2) return; //走到目的地便可
        for(int y = 1; y <= n; y++) if(!vis[y])
            d[y] = min(d[y], w[x][y]); //更新未接入的點的dist
    }

}

int main()
{
    int kcase = 0;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0) break;
        for(int i = 1; i <= n; i++)
        {
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }

        for(int i = 1; i <= n; i++)
        {
            w[i][i] = 0;
            for(int j = i+1; j <= n; j++)
            {
                w[i][j] = dist(p[i],p[j]);
                w[j][i] = dist(p[i],p[j]);
            }
        }

        ans = 0;
        Dijkstra();
        printf("Scenario #%d\n", ++kcase);
        printf("Frog Distance = %.3lf\n\n", ans);
    }
}
相關文章
相關標籤/搜索