POJ 2253 Frogger (單源最短路變型 求路徑上最大邊權值的最小值)

題目鏈接

POJ2253

題目大意

輸入N(2 N 200)個點的座標,任意兩點可以互相到達,經過的距離爲它們的歐式距離。現在從1號點到2號點有多條路徑,求這些路徑中最大邊權值的最小值。

分析

這題爲單源最短路的變型題。
首先建圖,由於點較少,用鄰接矩陣即可,任意兩點間建立無向邊,權值爲它們之間的歐式距離。
最原始的單源最短路問題可以求起點到終點間每條路徑各自的權值和的最小值,而這道題是每條路徑中最大邊權值的最小值,原來dis[i]維護的是源點到i號頂點的最短總路徑長度,現在dis[i]維護源點到i頂點最大邊權值,相應地,鬆弛操作改寫爲:dis[i]=max(dis[j],a[i][j]);即可,用Dijkstra、SPFA都行。

代碼

SPFA+鄰接矩陣

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#define Max(a,b) (a>b?a:b)
using namespace std;
const int INF=99999999;
double e[205][205],dis[205];
int book[205];

void SPFA(int n)
{
    queue<int> Q;
    int i,j;
    for (i=1;i<=n;i++)
    {
        dis[i]=INF;
        book[i]=0;
    }
    dis[1]=0;
    book[1]=1;
    Q.push(1);//源點入隊
    while (!Q.empty())
    {
        i=Q.front();
        Q.pop();
        book[i]=0;
        for (j=1;j<=n;j++)//掃描當前頂點i所有出邊
            if (dis[j]>Max(dis[i],e[i][j]))//判斷是否鬆弛成功
            {
                dis[j]=Max(dis[i],e[i][j]);
                if (!book[j])//判斷j是否在隊列中
                {
                    Q.push(j);
                    book[j]=1;;
                }
            }
    }
}
int main()
{
    int x[205],y[205],n,i,j,t;
    t=0;
    while (scanf("%d",&n)!=EOF)
    {
        if (n==0) break;
        for (i=1;i<=n;i++)
            scanf("%d%d",&x[i],&y[i]);
        for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            e[i][j]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));//建圖
        SPFA(n);
        printf("Scenario #%d\n",++t);
        printf("Frog Distance = %.3f\n\n",dis[2]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章