社区讨论

关于dijkstra+堆过了标准版但没过弱化版。

灌水区参与者 6已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@lo27n8ze
此快照首次捕获于
2023/10/23 09:19
2 年前
此快照最后确认于
2023/11/03 09:34
2 年前
查看原帖
CPP
#include <iostream>
#include <queue> //使用小根堆维护
#define big long long
using namespace std;
big n,m,s,cnt=0;
big a,b,v;
big getto[200005],value[200005],nxt[200005],point[100005];
big dis[100005],vis[100005];
struct Node{
    big val,point;
    friend bool operator < (Node l,Node r)
    {
        return l.val > r.val;
    }//以 dis_i 为关键字排序
}tmp;
priority_queue <Node> q;//使用小根堆维护。
void build(big a,big b,big v)
{
    cnt++;
    getto[cnt] = b;
    value[cnt] = v;
    nxt[cnt] = point[a];
    point[a] = cnt;
}//链式前向星
void dijkstra()
{
    for(big i = 1;i <= n;i++)//初始化
    {
        dis[i] = 2147483647;
    }
    dis[s] = 0;//起点最短路为0。
    tmp.point = s;
    tmp.val = 0;
    q.push(tmp);
    while(!q.empty())
    {
        big u = q.top().point;//已经进行小根堆维护,直接找到最小点。
        
        q.pop();//下一次不需要处理该点。
        if(vis[u])
        {
            continue;
        }//处理过,寻找下一个。
        vis[u] = 1;//找到点,标记为走过。
        for(big i = point[u];i ;i = nxt[i])//遍历所有 u -> i。
        {
            if(dis[getto[i]] > dis[u]+value[i])//目前到 u 的最短路+value[u -> i] < 目前到 i 的最短路(松弛操作)
            {
                dis[getto[i]] = dis[u]+value[i]; //更新最短路
                tmp.val = dis[getto[i]];
                tmp.point = getto[i];
                q.push(tmp);//更新堆,重新排序。
            }
        }
    }
}
int main()
{
    cin >> n >> m >> s;
    for(big i = 1;i <= m;i++)
    {
        scanf("%lld %lld %lld",&a,&b,&v);
        build(a,b,v);
    }
    dijkstra();
    for(big i = 1;i <= n;i++)
    {
        printf("%lld ",dis[i]);
    }
    return 0;
}// O(n^2 + m) => O(m log_m)
//单元最短路径(弱化版)

回复

11 条回复,欢迎继续交流。

正在加载回复...