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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值