[Usaco2009 Oct]Heat Wave 热浪

这篇博客介绍了如何运用Dijkstra算法解决无向图中从源点到目标点的最短路径问题。通过输入一个有向图的节点数、边数、起始点和目标点,程序会计算并输出最短路径长度。代码实现中采用了优先队列(大根堆)进行优化,确保了算法的效率。

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

题目描述

有一个 n个点 m 条边的无向图,请求出从 s 到 t 的最短路长度。


输入格式第一行四个正整数 n, m, s, t。 接下来 m 行,每行三个正整数 u, v, w,表示一条连接 u, v 长为 w 的边。

1≤n≤2500,1≤m≤6200,1≤w≤1000。


输出格式

输出一行一个整数,表示答案。


样例输入

Copy to Clipboard
7 11 5 4 
 2 4 2
 1 4 3
 7 2 2
 3 4 3
 5 7 5
 7 3 3
 6 1 1
 6 3 4
 2 4 3
 5 6 3
 7 2 1 

样例输出

Copy to Clipboard
7
/*
 * @Description: To iterate is human, to recurse divine.
 * @Autor: Recursion
 * @Date: 2022-03-02 11:52:08
 * @LastEditTime: 2022-03-24 12:07:32
 */
#include <bits/stdc++.h>
#define Inf 2147483647
using namespace std;
int head[(int)1e6+10],cnt;
int dis[(int)1e6+10],vis[(int)1e6+10];
int n,m,s;

void init()
{
    for(int i = 1;i <= n;i ++)
        dis[i] = Inf;
}

struct edge{
    int to;
    int weight;
    int next;//终点,边权,同起点的上一条边的编号
}edge[(int)1e6+10];

struct node{
    int w;
    int now;
    //重载运算符把最小的元素放在堆顶(大根堆)
    bool operator <(const node &x)const
    {
        return w > x.w;
    }
};

priority_queue<node>q;

void add(int u,int v,int w)
{
    edge[++cnt].to = v;
    edge[cnt].weight = w;
    edge[cnt].next = head[u];//存储该点的下一条边
    head[u] = cnt;//更新目前该点的最后一条边(就是这一条边)
}

void dijkstra()
{ 
    for(int i = 1;i <= n;i ++)
        dis[i] = Inf;
    dis[s] = 0;
    q.push((node){0,s}); 
    while(!q.empty()){
        //堆为空所以节点都更新
        node x = q.top();
        q.pop();
        int u = x.now;
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = head[u];i;i = edge[i].next){
            int v = edge[i].to;
            if(dis[v] > dis[u] + edge[i].weight){
                dis[v] = dis[u] + edge[i].weight;
                q.push((node){dis[v],v});
            }
        }
    }
}

int main()
{
    int t;
    cin >> n >> m >> s >> t;
    init();
    for(int i = 1;i <= m;i++)
    {
        int x,y,z;
        cin >> x >> y >> z;
        add(x,y,z);
        add(y,x,z);
    }
    //dijkstra();
    int pos = s;
    dis[pos] = 0;
    while(vis[pos] == 0){
        int minn = Inf;
        vis[pos] = 1;
        for(int i = head[pos];i!=0;i = edge[i].next){
            if(!vis[edge[i].to]&&(dis[edge[i].to] > dis[pos] + edge[i].weight))
                dis[edge[i].to] = dis[pos] + edge[i].weight;
        }
        for(int i = 1;i<=n;i++)
            if(dis[i] < minn&&vis[i] == 0){
                minn = dis[i];
                pos = i;
            }
    } 
    cout << dis[t] << endl;
    // for(int i = 1;i <= n;i ++)
    //     cout << dis[i] << " ";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值