bzoj3694 最短路 并查集(树链剖分)
来源:互联网 发布:淘宝客服主管培训课程 编辑:程序博客网 时间:2024/06/15 05:39
题意:给出一个图和他的最短路树,让你求不经过最短路最后一条边的最短路。
。。一开始以为直接上次短路,后来发现zz了,并不可以。。
然后%了一发题解。
其实就是要在最短路树之外找一条路径来跑。。
那么假设现在有一条非树边x-y,长度为len。
那么我们对于t=lca(x,y)(假设y在树上x不在),可以把1-i的路径转化为(i在t到y之间)1-t-x-y-i.
这样的路径长度是dis[x]+dis[y]+len-dis[i].
由于最短路固定为只有1条,所以dis[i]固定不变,那么我们要让dis[x]+dis[y]+len最短。
所以我们可以用这个值去更新t-y所有点(不包括t)的最短路长度.
可以用线段树(树链剖分)也可以用并查集。
这里只讲一下并查集。
先把所有非树边排个序然后逐个更新。
然后我们发现已经被更新过的点不可能被更新(代价越来越大)。
所以我们可以用并查集维护个已经被更新过的lca。 一点都不觉得树剖显然(,可能我比较蠢
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=2e5+5;int n,m;int tot,head[N],next[N],go[N],val[N],f[N],cnt;int fa[N],bel[N],dis[N],h[N];struct node{ int x,y,l,len;}edge[N];inline void add(int x,int y,int z){ go[++tot]=y; val[tot]=z; next[tot]=head[x]; head[x]=tot;}inline void dfs(int x,int fat,int dep){ h[x]=dep; fa[x]=fat; for(int i=head[x];i;i=next[i]) { int v=go[i]; if (v!=fat) { dis[v]=dis[x]+val[i]; dfs(v,x,dep+1); } }}inline int find(int x){ if (x==f[x])return x; else return f[x]=find(f[x]);}inline bool cmp(node a,node b){ return a.len<b.len;}int main(){ scanf("%d%d",&n,&m); fo(i,1,m) { int a,b,l,t; scanf("%d%d%d%d",&a,&b,&l,&t); if (t==1) add(a,b,l),add(b,a,l); else edge[++cnt].x=a,edge[cnt].y=b,edge[cnt].l=l; } dfs(1,0,1); fo(i,1,cnt) edge[i].len=edge[i].l+dis[edge[i].x]+dis[edge[i].y]; sort(edge+1,edge+1+cnt,cmp); fo(i,1,n)f[i]=i; fo(i,1,cnt) { int x=edge[i].x,y=edge[i].y; int fx=find(x),fy=find(y); int lastx=0,lasty=0; while (fx!=fy) { if (h[fx]<h[fy])swap(x,y),swap(fx,fy),swap(lastx,lasty); if (!bel[x]) { bel[x]=i; if (lastx)f[lastx]=x; } else if (lastx)f[lastx]=x; lastx=fx; x=fa[lastx]; fx=find(x); } } if (bel[2])printf("%d",edge[bel[2]].len-dis[2]); else printf("-1"); fo(i,3,n) if (bel[i])printf(" %d",edge[bel[i]].len-dis[i]); else printf(" -1"); return 0;}
0 0
- [BZOJ3694]最短路(并查集)
- bzoj3694 最短路 并查集(树链剖分)
- 【bzoj3694】【最短路】【树链剖分】
- [bzoj3694]最短路 树链剖分
- bzoj3694 最短路(最短路+树链剖分维护最小值)
- BZOJ3694 最短路 [最短路径树]
- hdu 5361 In Touch(最短路+并查集)
- HDU 5361(最短路+并查集优化)
- hdu5361(最短路+并查集)
- HDU5361In Touch (最短路+并查集)
- hdu5361 最短路+并查集
- 做运动 并查集+最短路
- [Usaco2009 Jan]安全路经Travel(最短路树+并查集/树链剖分)
- hdu1598_贪心+并查集=最短路
- USACO section 2.4 Cow Tours(并查集+最短路)
- 并查集&最小生成树、最短路
- poj 2253 Frogger 【枚举+并查集 or 最短路】
- Google Spaceship Defence 面试题目 并查集+最短路
- 一步步分析SpringMVC源码
- Maven环境搭建和介绍
- Jquery属性过滤选择器
- 头疼的闭包
- c++重载[]运算符
- bzoj3694 最短路 并查集(树链剖分)
- java容器(一)概述
- 2017山东省第八届ACM竞赛总结
- Hibernate基础配置文件
- 焦距、物距、像距
- POJ 2409 Let it Bead
- Python进阶之装饰器
- 欢迎使用CSDN-markdown编辑器
- 自己写个轮播图效果