首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 2627 Gopher and Hawks:最短路判斷老鼠能否到達

     編輯:關於C++

問題描述

老鼠從洞 1 出發,速度 v,最多在洞外停留 m 分鐘。地面有 n 個洞(坐標)。老鼠能在兩洞間直線跑動,距離 ≤ v * m * 60 米則可到達。求能否從洞 1 到洞 2,能則輸出最少中轉洞數(不含起點終點)。

建模:無權圖最短路

  • 節點:洞(含起點 0、終點 1)。
  • 邊:兩洞距離 ≤ 最大跑動距離,雙向邊,權重 1。
  • 求 0 到 1 的最短路徑長度(邊數)。答案 = 距離 - 1(中轉洞數)。

距離計算與精度

坐標輸入為浮點數(如 1.234)。為避免精度問題,放大 1000 倍轉整數:
int64 x = llround(input * 1000)。
距離平方比較:(dx*dx + dy*dy) <= (v * m * 60 * 1000)^2。
所有運算用 64 位整數,無浮點誤差。

代碼實現 (C++,SPFA/BFS)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Pt { ll x, y; };
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll v, m;
    while (cin >> v >> m) {
        ll maxd = v * m * 60 * 1000; // 放大 1000 後的最大距離
        vector pts;
        double x, y;
        while (cin >> x >> y) {
            pts.push_back({llround(x * 1000), llround(y * 1000)});
        }
        int n = pts.size();
        vector> adj(n);
        for (int i = 0; i < n; ++i) {
            for (int j = i+1; j < n; ++j) {
                ll dx = pts[i].x - pts[j].x;
                ll dy = pts[i].y - pts[j].y;
                if (dx*dx + dy*dy <= maxd*maxd) {
                    adj[i].push_back(j);
                    adj[j].push_back(i);
                }
            }
        }
        // BFS 求最短路(無權圖)
        vector dist(n, -1);
        queue q;
        dist[0] = 0; q.push(0);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : adj[u]) if (dist[v] == -1) {
                dist[v] = dist[u] + 1;
                q.push(v);
            }
        }
        if (dist[1] == -1) cout << "No.\n";
        else cout << "Yes, visiting " << dist[1] - 1 << " other holes.\n";
    }
    return 0;
}

複雜度

  • 建圖:O(n²),n ≤ 1000(隱含),約 5e5 邊,可接受。
  • BFS:O(n + m)。
  • 空間:O(n²) 邊表。

關鍵點

  • 浮點坐標 → 整數放大,避免精度誤差導致邊漏判/誤判。
  • 無權圖最短路用 BFS 即可,SPFA 過度。
  • 輸入以 EOF 結束,每測試用例先讀 v,m,再讀坐標直到文件末尾或下一用例(題目格式需注意,實際 POJ 2627 每用例坐標行數不固定,通常先給 n?原題輸入格式:v m 然後多行坐標直到 EOF 或空行。代碼中用 `while(cin>>x>>y)` 讀完所有坐標)。

這題是「幾何距離建圖 + BFS 最短路」的典型應用,整數放大技巧解決浮點精度問題,代碼清晰實用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved