luogu P4366 [Code+#4]最短路 |最短路

Posted naruto-mzx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P4366 [Code+#4]最短路 |最短路相关的知识,希望对你有一定的参考价值。

题目描述

企鹅国中有 NNN 座城市,编号从 111 到 NNN 。

对于任意的两座城市 iii 和 jjj ,企鹅们可以花费 (i xor j)×C(i~mathrm{xor}~j) imes C(i xor j)×C 的时间从城市 iii 走到城市 jjj ,这里 CCC 为一个给定的常数。

当然除此之外还有 MMM 条单向的快捷通道,第 iii 条快捷通道从第 FiF_iFi??? 个城市通向第 TiT_iTi??? 个城市,走这条通道需要消耗 ViV_iVi??? 的时间。

现在来自 Penguin Kingdom University 的企鹅豆豆正在考虑从城市 AAA 前往城市 BBB 最少需要多少时间?

输入格式

从标准输入读入数据。

输入第一行包含三个整数 N,M,CN,M,CN,M,C ,表示企鹅国城市的个数、快捷通道的个数以及题面中提到的给定的常数CCC。

接下来的 MMM 行,每行三个正整数 Fi,Ti,ViF_i,T_i,V_iFi?,Ti?,Vi?? (1≤Fi≤N1 leq F_i leq N1≤Fi?≤N,1≤Ti≤N,1≤Vi≤1001 leq T_i leq N ,1leq V_i leq 1001≤Ti?≤N,1≤Vi?≤100),分别表示对应通道的起点城市标号、终点城市标号和通过这条通道需要消耗的时间。

最后一行两个正整数 A,BA,BA,B (1≤C≤100)(1 leq C leq 100)(1≤C≤100),表示企鹅豆豆选择的起点城市标号和终点城市标号。

输出格式

输出到标准输出。

输出一行一个整数,表示从城市 AAA 前往城市 BBB 需要的最少时间


按照数位建边

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int _=3e5+10;
int nxt[_<<3],head[_],go[_<<3],w[_<<3],tot;
inline void add(int u,int v,int o){
    nxt[++tot]=head[u];head[u]=tot;go[tot]=v;w[tot]=o;
}
struct node{
    int u,d;
    bool operator<(const node&rhs)const{
        return d>rhs.d;
    }
};
priority_queue<node>q;
int dis[_];
void dj(int s){
    memset(dis,0x7f,sizeof(dis));
    dis[s]=0; q.push((node){s,0});
    while(q.size()){
        int u=q.top().u;
        int d=q.top().d;
        q.pop();
        if(dis[u]!=d)continue;
        for(int i=head[u];i;i=nxt[i]){
            int v=go[i];
            if(dis[v]>dis[u]+w[i]){
                dis[v]=dis[u]+w[i];
                q.push((node){v,dis[v]});
            }
        }   
    }
}
inline int read(){
    int x=0; char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while('0'<=c&&c<='9'){ x=(x<<1)+(x<<3)+c-'0'; c=getchar();  }
    return x;
}
#define re register int
signed main(){
    int n=read(),m=read(),c=read();
    for(re i=1,u,v;i<=m;i++){
        u=read(),v=read();
        add(u,v,read());
    }
    for(re i=1;i<=n;i++)
    for(int j=0,v;j<=16;j++){
         v=i^(1<<j);
         if(v<=n)add(i,v,c*(1<<j));
    }
    dj(read());
    cout<<dis[read()]<<endl;
}

以上是关于luogu P4366 [Code+#4]最短路 |最短路的主要内容,如果未能解决你的问题,请参考以下文章

luogu4366 [Code+#4]最短路[优化建边最短路]

luogu 4366 [Code+#4]最短路 Dijkstra + 位运算 + 思维

[Code+#4]最短路 解题报告

Luogu2149 [SDOI2009]Elaxia的路线-最短路+拓扑排序

LOJ6354 & 洛谷4366:[Code+#4]最短路——题解

Luogu5905 模板Johnson 全源最短路