Dijkstra 算法求最大載重和最小跳躍距離?(最短路?)

② - POJ 1797 -

Heavy Transportation

Time Limit: 3000MS | Memory Limit: 30000K

題意:

第一行給定一個整數 T ,表示測試案例數;
每個測試案例第一行給定整數 n、m,分別表示地點數和街道/橋樑的數量;
接下來 m 行,每行三個正整數 a、b、d,表示 a、b 之間的街道/橋樑能承受的最大重量爲 d;
求運輸車從地點 1 到地點 n 可能的最大載重。
輸出格式:第一行輸出"Scenario #x"(x表示從1開始的第幾個測試案例),第二行輸出一個整數,表示最大載重。

數據範圍:

1 <= n <= 1000; a,b,c<=1000000

解題思路:

Dijkstra(貌似是Prim?,不礙事,能把題目做出來就行~)

這題要求從 1 到 n 運輸車可能的最大載重,那麼就可以從起點 1 開始,每次都選取承載重量最大的路走,抵達目的地之時就停止該操作,那麼這些路中承載重量最小的路的承載重量就是運輸車可能的最大載重。

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
#define INF 0x3f3f3f
#define zero 1e-7
typedef long long ll;
const int N=1005;

int mp[N][N], dis[N];
bool vis[N];

int Dijkstra(int n) {
    memset(vis, false, sizeof(vis));
    vis[1]=true;
    for(int i=1; i<=n; i++)
        dis[i]=mp[1][i];
    int res=INF;
    for(int i=1; i<n; i++) {
        int maxw=0, temp;
        for(int j=2; j<=n; j++) {
            if(dis[j]>maxw && !vis[j]) {
                maxw=dis[j];
                temp=j;
            }
        }
        vis[temp]=true;
        res=min(res, maxw);
        if(temp==n) break;
        for(int j=2; j<=n; j++) {
            if(mp[temp][j]>dis[j] && !vis[j])
                dis[j]=mp[temp][j];
        }
    }
    return res;
}

int main() {
    int T, n, m, a, b, d;
    scanf("%d",&T);
    for(int t=1; t<=T; t++) {
        scanf("%d %d", &n, &m);
        memset(mp, 0, sizeof(mp));
        while(m--) {
            scanf("%d %d %d", &a, &b, &d);
            mp[a][b]=mp[b][a]=d;
        }
        int ans=Dijkstra(n);
        printf("Scenario #%d:\n%d\n\n", t, ans);
    }
    return 0;
}

① - POJ 2253 -

Frogger

Time Limit: 1000MS | Memory Limit: 65536K

題意:

情境:青蛙 Freddy(弗雷迪)想要到青蛙 Fiona(菲奧娜)那去,但是距離太遠超出了它的跳躍範圍,於是它想通過湖中的其它石頭跳到 Fiona 所在的石頭上。
有多個測試案例,每個測試案例第一行給定一個整數 n ,表示湖中的石頭數量,接下來 n 行,每行兩個整數 xi、yi,表示石頭 i 的座標,青蛙 Freddy 和 Fiona 分別在 1 號和 2 號石頭上,求青蛙距離(即 Freddy 到 Fiona 那去至少要能跳多遠,也叫最小-最大距離)。當 n=0 時輸入結束。
輸出格式:第一行輸出"Scenario #x"(x表示從1開始的第幾個測試案例),第二行輸出"Frog Distance = y"(y即青蛙距離)。

數據範圍:

2<=n<=200,0 <= xi,yi <= 1000

解題思路:

姑且稱之爲 Dijkstra 算法吧

這題要求青蛙從 1 到 2 至少要能跳多遠,那麼,就可以先把每兩塊石頭之間的距離算出來,然後從 1 出發,每次都選取距離最小的那塊石頭作爲下一次的落腳點,抵達 2 號石頭時就停止跳躍,那麼這些距離中的最大距離就是青蛙距離。

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
#define INF 0x3f3f3f
#define zero 1e-7
typedef long long ll;
const int N=205;

double mp[N][N], dis[N];
bool vis[N]={false};
int x[N], y[N], t=0;

void Dijkstra(int n) {
    vis[1]=true;
    for(int i=1; i<=n; i++)
        dis[i]=mp[1][i];
    double res=0;
    for(int i=1; i<n; i++) {
        double mind=INF;
        int temp=1;
        for(int j=2; j<=n; j++) {
            if(dis[j]<mind && !vis[j]) {
                mind=dis[j];
                temp=j;
            }
        }
        res=max(res, mind);
        vis[temp]=true;
        if(temp==2) break;
        for(int j=2; j<=n; j++) {
            if(mp[temp][j]<dis[j] && !vis[j])
                dis[j]=mp[temp][j];
        }
    }
    printf("Scenario #%d\n", t);
    printf("Frog Distance = %.3f\n\n", res);
    return ;
}

int main() {
    int n, a, b;
    while(scanf("%d", &n)!=EOF, n) {
        t++;
        for(int i=1; i<=n; i++)
            scanf("%d %d", &x[i], &y[i]);
        for(int i=1; i<=n; i++) {
            for(int j=i; j<=n; j++) {
                mp[i][j]=mp[j][i]=sqrt((double)((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
            }
        }
        memset(vis, false, sizeof(vis));
        Dijkstra(n);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章