题目大意:

给你一张无向图,求1到其他节点 不经过最短路的最后一条边 的最短路长度,保证每个节点的最短路走法唯一

神题,$USACO$题目的思维是真的好

先$dijkstra$出最短路树

对于每个节点,符合条件的走法必须满足,不经过它和它父亲之间的连边

显然只能从它的某个子节点走向它,就像绕了一圈

可以证明最优的合法路径一定只经过一条非树边,因为最短路方案唯一

如果还经过另外一条非树边,不论这条边在哪,都肯定会绕远

对于一条非树边$e<x,y>$,它连接了两个节点$x,y$,它们的$lca$是$f$

显然$x$到$f$路径上的某个点$S$(除了$f$点),都存在一条合法路径,从根节点沿树边走到$y$,经过$e<x,y>$走到$x$,再向上沿树边走到$S$

这段路径的长度是$dis_{x}+dis_{y}+dis_{e<x,y>}-dis_{S}$

对于$y$到$f$的路径也是同理

上面的式子可以用线段树+树链剖分序维护

  1. #include <queue>
  2. #include <vector>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #define N1 1010
  7. #define M1 2010
  8. #define S1 (N1<<1)
  9. #define T1 (N1<<2)
  10. #define ll long long
  11. #define uint unsigned int
  12. #define rint register int
  13. #define dd double
  14. #define il inline
  15. #define inf 233333333
  16. using namespace std;
  17.  
  18. int gint()
  19. {
  20. int ret=,fh=;char c=getchar();
  21. while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
  22. while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
  23. return ret*fh;
  24. }
  25. int n,m;
  26. struct Edge{
  27. int to[M1*],nxt[M1*],val[M1*],head[N1],cte;
  28. void ae(int u,int v,int w)
  29. {cte++,to[cte]=v,nxt[cte]=head[u],val[cte]=w,head[u]=cte;}
  30. }E,T;
  31. struct SEG{
  32. int mi[T1];
  33. void pushdown(int rt)
  34. {
  35. mi[rt<<]=min(mi[rt<<],mi[rt]);
  36. mi[rt<<|]=min(mi[rt<<|],mi[rt]);
  37. }
  38. void build(int l,int r,int rt)
  39. {
  40. mi[rt]=inf;
  41. if(l==r) return;
  42. int mid=(l+r)>>;
  43. build(l,mid,rt<<);
  44. build(mid+,r,rt<<|);
  45. }
  46. void update(int L,int R,int l,int r,int rt,int w)
  47. {
  48. if(L<=l&&r<=R) {mi[rt]=min(mi[rt],w);return;}
  49. int mid=(l+r)>>; pushdown(rt);
  50. if(L<=mid) update(L,R,l,mid,rt<<,w);
  51. if(R>mid) update(L,R,mid+,r,rt<<|,w);
  52. }
  53. int query(int x,int l,int r,int rt)
  54. {
  55. if(l==r) return mi[rt];
  56. int mid=(l+r)>>; pushdown(rt);
  57. if(x<=mid) return query(x,l,mid,rt<<);
  58. else return query(x,mid+,r,rt<<|);
  59. }
  60. }s;
  61.  
  62. int dis[N1],use[N1],fa[N1],la[N1],ist[M1*];
  63. struct node{
  64. int id,d;
  65. friend bool operator < (const node &s1,const node &s2)
  66. {return s1.d>s2.d;}
  67. };
  68. void dijkstra()
  69. {
  70. int j,v,u;
  71. memset(dis,0x3f,sizeof(dis));
  72. priority_queue<node>q;
  73. dis[]=,q.push((node){,});
  74. while(!q.empty())
  75. {
  76. node k=q.top(); q.pop(); u=k.id;
  77. if(use[u]) continue; use[u]=;
  78. for(j=E.head[u];j;j=E.nxt[j]){
  79. v=E.to[j];
  80. if(dis[v]>dis[u]+E.val[j])
  81. dis[v]=dis[u]+E.val[j],q.push((node){v,dis[v]}),fa[v]=u,la[v]=j;
  82. }
  83. }
  84. }
  85.  
  86. int dep[N1],sz[N1],tp[N1],son[N1],st[N1],id[N1],tot;
  87. void dfs1(int u,int dad)
  88. {
  89. for(int j=T.head[u];j;j=T.nxt[j])
  90. {
  91. int v=T.to[j]; if(v==dad) continue;
  92. dep[v]=dep[u]+; dfs1(v,u); //fa[v]=u;
  93. sz[u]+=sz[v]; son[u]=sz[v]>sz[son[u]]?v:son[u];
  94. }
  95. sz[u]++;
  96. }
  97. void dfs2(int u)
  98. {
  99. st[u]=++tot,id[tot]=u;
  100. if(son[u]) tp[son[u]]=tp[u],dfs2(son[u]);
  101. for(int j=T.head[u];j;j=T.nxt[j])
  102. {
  103. int v=T.to[j];
  104. if(v==son[u]||v==fa[u]) continue;
  105. tp[v]=v; dfs2(v);
  106. }
  107. }
  108. void update(int x,int y,int w)
  109. {
  110. int px=x,py=y;
  111. while(tp[x]!=tp[y])
  112. {
  113. if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
  114. s.update(st[tp[x]],st[x],,n,,dis[px]+dis[py]+w);
  115. x=fa[tp[x]];
  116. }
  117. if(dep[x]>dep[y]) swap(x,y);
  118. if(x!=y) s.update(st[x]+,st[y],,n,,dis[px]+dis[py]+w);
  119. }
  120.  
  121. void solve()
  122. {
  123. int x,y,i,j,v,ans; dijkstra(); s.build(,n,);
  124. for(i=;i<=n;i++) T.ae(fa[i],i,E.val[la[i]]),ist[la[i]]=;
  125. dep[]=,dfs1(,-); tp[]=,dfs2();
  126. for(j=;j<=m*;j+=)
  127. {
  128. if(ist[j]||ist[j+]) continue;
  129. x=E.to[j],y=E.to[j+];
  130. update(x,y,E.val[j]);
  131. }
  132. for(i=;i<=n;i++)
  133. {
  134. ans=s.query(st[i],,n,);
  135. if(ans==inf) printf("-1\n");
  136. else printf("%d\n",ans-dis[i]);
  137. }
  138. }
  139.  
  140. int main()
  141. {
  142. scanf("%d%d",&n,&m);
  143. int i,j,x,y,z;E.cte=;
  144. for(i=;i<=m;i++) x=gint(),y=gint(),z=gint(),E.ae(x,y,z),E.ae(y,x,z);
  145. solve();
  146. return ;
  147. }

BZOJ 1576 [USACO]安全路经Travel (树剖+线段树)的更多相关文章

  1. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  2. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  3. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  4. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  8. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

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

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

随机推荐

  1. twemproxy 安装与配置

    转自:http://blog.csdn.net/u011183653/article/details/21240749 说到twemproxy就不得不说要一下redis,这是因为twemproxy是为 ...

  2. Oracle 知识积累

    1.oracle存储过程中is和as的区别 在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别,在视图(VIEW)中只能用AS不能用IS,在游标(CURSOR)中只能用IS不能用AS ...

  3. sublime 自定义快捷生成代码块

    菜单栏目选 Tools(工具) =>Developer(插件开发)=>New Snippet....(新建代码片段),如图: 接着会新开一个标签页,会附带一些内容:如图: 将“Hello, ...

  4. webpack使用中遇到的相关问题

    问题一:使用webpack打包jquery后,在页面使用错误信息:$ is not defined new webpack.ProvidePlugin({ "$": "j ...

  5. Project Euler 44 Sub-string divisibility( 二分 )

    题意:五边形数由公式Pn=n(3n−1)/2生成,在所有和差均为五边形数的五边形数对Pj和Pk中,找出使D = |Pk − Pj|最小的一对:此时D的值是多少? 思路:二分找和差 /********* ...

  6. 学习笔记——ST表

    作用: 给定一个数列 ai O(nlogn) 预处理 O(1) 查询区间最值 实现: 定义f(i,j) 为ai开始,包括ai的连续2^j个元素的最值 下面以最大值为例: f(i,j)表示max{ak} ...

  7. [BZOJ4916]神犇(Monster_Qi)和蒟蒻(SWHsz)

    很久很久以前,有一只神犇叫Monster_Qi; 很久很久之后,有一只蒟蒻叫SWHsz; 1<=N<=1E9,A.B模1E9+7; 求这个. 求μ的话直接输出1就行了因为除了1的平方外都有 ...

  8. Mac python3 环境下 完善pdf转jpg脚本

    由于样本图片数据都是保存在pdf里,想拿到样本必须先把图片从pdf中提取出来,算是数据清洗中的一点小小的积累吧. 这里不得不吐槽一下公司存储图片的机制,业务员把jpg格式的照片放到word里,然后用工 ...

  9. InfoSYS-20170114

    1.描述Spring的事务机制 2.描述并发脏数据,如何避免 3.如何防止同一个请求重复提交(重复付款) 4.如何监控程序性能 5.CPU过高说明什么问题 通常是程序中有死循环, 参考 http:// ...

  10. springboot配置容器

    servlet容器配置 Spring Boot快速的原因除了自动配置外,另一个就是将web常用的容器也集成进来并做自动配置,让使用它的人能更快速的搭建web项目,快速的实现自己的业务目的.什么是容器? ...