[kuangbin带你飞] 专题四 最短路练习 练习

本文深入探讨图算法中的两种经典问题——最短路径与最小跳跃距离。通过具体实例,讲解了使用前向星和邻接表实现Dijkstra算法求解最短路径,以及利用弗洛伊德算法寻找每条路径上跳跃的最大距离,并最终找到最小跳跃距离路径的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Til the Cows Come Home

 裸的最短路,wa一路发现自己T,N读入反了,据说还有重边,不过是邻接矩阵需要考虑的问题,前向星和邻接表可以忽略。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
typedef pair<int,int> Pi;
typedef unsigned long long ULL;
int Gcd(int a,int b){if (b == 0) return a; return Gcd(b , a%b);}
int Lcm(int a, int b){ return a/Gcd(a,b)*b;}
inline int read(){
    int f = 1, x = 0;char ch = getchar();
    while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
const int maxn = 1e6 + 10;
struct _edge{
    int to,nex,w;
}edge[maxn<<1];
int head[maxn],tot;
int dis[maxn];
int n,m,u,v,w;
void add(int u,int v,int w){
    edge[tot] = (_edge){v,head[u],w};
    head[u] = tot++;
}
void dij(int s){
    memset(dis,0x3f,sizeof(dis)); dis[s] = 0;
    priority_queue< Pi,vector<Pi>,greater<Pi> > pq; 
    pq.push(make_pair(0,s));   
    while(!pq.empty()){
        Pi now = pq.top(); pq.pop();
        int u = now.second;
        if (dis[u] < now.first) continue;
        for(int i=head[u]; ~i; i=edge[i].nex){
            int v = edge[i].to;
            if (dis[v] > dis[u] + edge[i].w){
                dis[v] = dis[u] + edge[i].w;
                pq.push(make_pair(dis[v],v));
            }
        }
    }
}
int main(){
    scanf("%d%d",&m,&n);
    memset(head,-1,sizeof(head));
    for(int i=0; i<m; i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }   
    dij(n);
    cout << dis[1] << endl;
    return 0;
}

 

2、Frogger

 弗洛伊德有dp的性质,找一条,每一跳都尽可能小的路径,找这个路径上的跳跃最大的距离

用 dis[i][j] 表示 i 到 j 距离最大的距离

则有  dis[i][j] = min(max(dis[i][k],dis[k][j]), dis[i][j]);

中间的max是路径上跳跃的最大距离,而外层的min代表最大跳跃距离尽可能小的路径

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
int Gcd(int a,int b){if (b == 0) return a; return Gcd(b , a%b);}
int Lcm(int a, int b){ return a/Gcd(a,b)*b;}
inline int read(){
    int f = 1, x = 0;char ch = getchar();
    while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
const int maxn = 1e3 + 10;
double dis[maxn][maxn];
double px[maxn],py[maxn];
int n;
int main(){
// /    freopen("/Users/chutong/ACM/data.in","r",stdin);
    int cas = 0;
    while(scanf("%d",&n) == 1 && n){
        cas++;
        for(int i=1; i<=n; i++){
            scanf("%lf%lf",&px[i],&py[i]);
            for(int j=1;j<=i-1; j++){
                dis[j][i] = dis[i][j] = sqrt((px[i]-px[j])*(px[i]-px[j]) + (py[i]-py[j])*(py[i]-py[j]));
            }
        }
        for(int k=1; k<=n; k++){
            for(int i=1; i<=n; i++){
                for(int j=1; j<=n; j++){
                    if (i != k && j != k)
                        dis[i][j] = min(max(dis[i][k],dis[k][j]),dis[i][j]);
                }
            }
        }
        printf("Scenario #%d\nFrog Distance = %.3f\n\n",cas,dis[1][2]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值