luogu P4366 [Code+#4]最短路 |最短路
题目描述
企鹅国中有 NNN 座城市,编号从 111 到 NNN 。
对于任意的两座城市 iii 和 jjj ,企鹅们可以花费 (i xor j)×C(i\mathrm{xor}j) \times 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 ,1\leq 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;
}
不以物喜,不以己悲