显然这里的$n^2$级别的边数不能全建出来,于是盯住xor这个关键点去 瞎猜 探究有没有什么特殊性质可以使得一些边没有必要建出来。

发现一个点经过一次xor $x$,花费$x$这么多代价(先不看$C$),到达另一个点$u\text{xor}x$。

结合异或性质,发现其实这个过程完全可以通过把$x$拆成一位一位去分别xor上$u$,也就是说,任何一个点到达另一个点只需要不断走$2^i$这种xor值就可以到达,于是每个点连出$logn$条边,分别和其序号二进制位每一位异或一个1的数相连。这样,如果要走一条xor路径,就可以拆成走若干条上述简化路径。于是建边就可以得到简化,总边数$m+n\text{log}n$,然后跑最短路即可。。

注意一个RE了无数发的detail:食用上述建边方法需要注意有部分超出$n$但小于$2^{log(n)+1}$的点建的边以及$0$号点连的边也是要考虑进去的,具体为什么自己想。。。于是乎这个数组大小不能照1e5来开了,开两倍2e5。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<queue>
  7. #define dbg(x) cerr << #x << " = " << x <<endl
  8. using namespace std;
  9. typedef long long ll;
  10. typedef double db;
  11. typedef pair<ll,int> pii;
  12. template<typename T>inline T _min(T A,T B){return A<B?A:B;}
  13. template<typename T>inline T _max(T A,T B){return A>B?A:B;}
  14. template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
  15. template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
  16. template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
  17. template<typename T>inline T read(T&x){
  18. x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
  19. while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
  20. }
  21. const int N=1e5+,M=+;
  22. struct thxorz{int to,nxt,w;}G[M];
  23. int Head[N<<],tot;
  24. int n,m,c,len,s,t;
  25. inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;}
  26. ll dis[N<<];
  27. priority_queue<pii,vector<pii>,greater<pii> >q;
  28. #define y G[j].to
  29. inline void dij(){
  30. memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[s]=,s));
  31. while(!q.empty()){
  32. ll d=q.top().first;int x=q.top().second;q.pop();
  33. if(t==x)break;
  34. if(d^dis[x])continue;
  35. for(register int j=Head[x];j;j=G[j].nxt)if(MIN(dis[y],d+G[j].w))q.push(make_pair(dis[y],y));
  36. }
  37. }
  38. #undef y
  39. int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
  40. read(n),read(m),read(c);
  41. for(register int i=,x,y,z;i<=m;++i)read(x),read(y),read(z),Addedge(x,y,z);
  42. len=__lg(n);read(s),read(t);
  43. for(register int i=;i<=(<<len+)-;++i)for(register int j=len;~j;--j)Addedge(i,i^(<<j),(<<j)*c);
  44. dij();
  45. return printf("%lld\n",dis[t]),;
  46. }

总结:对于边过多的图尝试发掘性质简化建边,去除没有必要的边,用如前缀/异或/线段树等方法来降低边数或者用少量边替代全部情况。

luogu4366 [Code+#4]最短路[优化建边最短路]的更多相关文章

  1. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  2. 【SDOI2017】天才黑客(前后缀优化建图 & 最短路)

    Description 给定一张有向图,\(n\) 个点,\(m\) 条边.第 \(i\) 条边上有一个边权 \(c_i\),以及一个字符串 \(s_i\). 其中字符串 \(s_1, s_2, \c ...

  3. CodeForces 786B Legacy(线段树优化建图+最短路)

    [题目链接] http://codeforces.com/problemset/problem/786/B [题目大意] 给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球, 从一个星球到另一 ...

  4. LOJ#6354. 「CodePlus 2018 4 月赛」最短路[最短路优化建图]

    题意 一个 \(n\) 个点的完全图,两点之间的边权为 \((i\ xor\ j)*C\) ,同时有 \(m\) 条额外单向路径,问从 \(S\) 到 \(T\) 的最短路. \(n\leq 10^5 ...

  5. Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)

    题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...

  6. 牛客网NOIP赛前集训营-提高组(第八场)-B-推箱子[最短路优化建图]

    题意 有 \(n\) 个箱子,指定一个箱子开始向右推,如果碰到了别的箱子会令其移动,问 \(k\) 秒之后每个箱子所在的位置. \(n\leq 10^5\). 分析 转化成最短路模型,如果两个箱子 \ ...

  7. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  8. 【LibreOJ】#6354. 「CodePlus 2018 4 月赛」最短路 异或优化建图+Dijkstra

    [题目]#6354. 「CodePlus 2018 4 月赛」最短路 [题意]给定n个点,m条带权有向边,任意两个点i和j还可以花费(i xor j)*C到达(C是给定的常数),求A到B的最短距离.\ ...

  9. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

随机推荐

  1. spring-boot和jboss应用添加pinpiont方式

    一.jboss应用 添加方式,添加方式,在run.conf文件配置pinpoint相关信息,如下: if [ "x$JAVA_OPTS" = "x" ]; th ...

  2. pmap 命令

    NAME pmap - report memory map of a process SYNOPSIS pmap [ -x | -d ] [ -q ] pids... pmap -V 常用参数: -x ...

  3. new与malloc有什么区别

    转自http://www.cnblogs.com/QG-whz/p/5140930.html 前言 几个星期前去面试C++研发的实习岗位,面试官问了个问题: new与malloc有什么区别? 这是个老 ...

  4. package[golang]学习笔记之context

    *关于context https://talks.golang.org/2014/gotham-context.slide#29

  5. INPUT和CONSTRUCT指令——范例报表查询,作用让用户输入数据,自动生成SQL的WHERE条件,带开窗查询

    INPUT指令 说明:1. 当程序执行到INPUT指令时,会将控制权交给用户,让用户输入数据.2. 用户输入完字段的数据,会将数据回传给程序中的变量接收.3. 只要执行到INPUT的指令,程序会将每个 ...

  6. 计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践

    计算广告CTR预估系列(七)--Facebook经典模型LR+GBDT理论与实践 2018年06月13日 16:38:11 轻春 阅读数 6004更多 分类专栏: 机器学习 机器学习荐货情报局   版 ...

  7. 深入理解计算机系统 第十章 系统级I/O 第二遍

    了解 Unix I/O 的好处 了解 Unix I/O 将帮助我们理解其他的系统概念 I/O 是系统操作不可或缺的一部分,因此,我们经常遇到 I/O 和其他系统概念之间的循环依赖.例如,I/O 在进程 ...

  8. audio隐藏下载按钮

    // 这个方法只支持 Chrome 58+, 低于该版本的是没有无法隐藏的 <audio src="/i/horse.ogg" controls="controls ...

  9. linq to sql之Distinct

    Distict用来排除相同序列中元素的,对于基础类型,可以直接使用Distinct,如:int[] a = {1, 2, 2, 3, 3, 3, 4};var reslut = a.Distinct( ...

  10. shiro学习(一)

    基础依赖: shiro-core,junit(因为在单元测试中) test.class public class AuthenticationTest { SimpleAccountRealm rea ...