社区讨论

能否这样实现多关键字最短路?

学术版参与者 4已保存回复 7

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@mhjdc108
此快照首次捕获于
2025/11/04 00:42
4 个月前
此快照最后确认于
2025/11/04 00:42
4 个月前
查看原帖
一条边的权值由 kk 个属性定义,比较优先级从高到低依次为 w1,w2,,wkw_1,w_2,\cdots,w_k
那么,按照这个算法流程是否能正确求出最短路?假设源点为 ss,总共 nn 个点。
注意,这里的小根堆的比较规则只关心第一关键字
CPP
定义一个用来存储节点的小根堆 pq,最短路的第一关键字最小的节点为堆顶。
定义 bool 数组 vis,大小为 n,初始默认全 0。
定义数组 dis,大小为 n,存储每个点的最短路。
pq.push(s)
dis[s] 的所有属性等于 0,因为是出发点
while(!pq.empty()){
    int u=pq.top();
    pq.pop();
    if(vis[u])continue;
    vis[u]=1;
    扫描所有 u 连接的点 v,令边权为 weight{
        if(dis[v].w[1] > dis[u].w[1]+weight){
            dis[v].w[1]=dis[u].w[1]+weight;
            dis[v] 的 w[2],w[3],.... 等属性赋值为 dis[u] 的。
            q.push(v)
        }else if(dis[v].w[1]==dis[u].w[1]+weight){
            dis[v] 的 w[2],w[3],.... 等属性与 dis[u] 的取 min,比较规则仍然按照一开始说的。
        }
    }
}
本意就是模拟 dijkstra 算法,但是没这么写过,故来洛谷问问。
换个说法,就是松弛过程中,vv 的最短路第一关键字可以用 uu 的最短路更新的情况下,先更新第一关键字,然后 vv 的其他关键字直接复制为 uu 的。
否则,如果vv 的最短路第一关键字等于 uu 的最短路的第一关键字。那么 vv 的其他关键字打包,与为 uu 的其他关键字打包的结果取 min。
换个人话,就是令 vv 的原来最短路的第二个关键字及以后组成 (p2,p3,,pk)(p_2,p_3,\cdots,p_k)uu 的最短路的第二个关键字及以后组成 (q2,q3,,qk)(q_2,q_3,\cdots,q_k),用后缀对前者取 min。
另外,如果这个不对,那么,它是否在第一关键字,或者所有的关键字边权都只有 11 的情况下正确?

回复

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

正在加载回复...