1. 程式人生 > >POJ #2253 Frogger 變種Dijkstra

POJ #2253 Frogger 變種Dijkstra

aps 路徑 lose script lap 只需要 efi double log

Description

  問題描述:鏈接

思路

  題目的意思是青蛙想從第一塊石頭跳到第二塊石頭,中間有許多墊腳石,求能跳到第二塊石頭的路上至少需要跳多遠。拿第二個樣例來說,頂點 1 到頂點 2 有兩條路分別為:1(根號2)3(根號2)21(2)2 ,括號裏的值表示相鄰兩點的距離。其中前一條路青蛙至少得具有根號2的跳躍能力才能到達第二塊石頭,後一條路需要具有2的跳躍能力。由於兩條路都能到達頂點2,那麽青蛙的跳躍能力只需要根號2即可。

  實質上,這道題就是求所有通路的最大邊的最小值。

  我們讓 d 數組中存儲所有從頂點1到頂點v的可達路徑中最大邊的最小值,那麽依舊可以使用 Dijkstra 貪心得到頂點1到頂點2的可達路徑中最大邊的最小值。由於比較的是某條邊的權,所以需要將松弛條件改成如下形式:

d[v] > max( d[u], w(u, v) )

AC代碼:

技術分享圖片
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iomanip>
using namespace std;
#define INF 0x3f3f3f3f
const int MAX_N = 210;
int n;
int x[MAX_N], y[MAX_N];

//u點到v點的距離
double w (int u, int v) {
    
return sqrt((double)(x[v] - x[u])*(x[v] - x[u]) + (y[v] - y[u])*(y[v] - y[u])); } double d[MAX_N]; bool vis[MAX_N]; void dijkstra (const int& s) { for (int i = 1; i <= n; ++i) d[i] = INF, vis[i] = false; d[1] = 0; for (int i = 1; i <= n; ++i) { double min_d = INF;
int u; for (int j = 1; j <= n; ++j ) { if ( !vis[j] && d[j] < min_d ) { min_d = d[j]; u = j; } } vis[u] = true; //圖為無向圖,所有頂點都有 n-1 條鄰接邊 for (int v = 1; v <= n; ++v) { if ( d[v] > max (d[u], w(u, v) ) ) { d[v] = max (d[u], w(u, v) ); } //d[v] = min (d[v], max(d[u], w(u, v))); } } } int main (void) { int test_num = 0; while (cin >> n && n ) { for (int i = 1; i <= n; ++i) { cin >> x[i] >> y[i]; } dijkstra (1); cout << "Scenario #" << ++test_num << endl << "Frog Distance = " << setiosflags(ios::fixed) << setprecision(3) << d[2] << endl << endl; } return 0; }
View Code

  

POJ #2253 Frogger 變種Dijkstra