Description

下水道的主干路由n个节点和n-l条边组成,每条边有一个通过它所需的时间Ti。换言之,这是一棵n个节点的带权树。现在,要用最快的速度赶往目标节点k。下水道有一些塌陷,这导致主干路的某一段路径可以通过该塌陷到另一条路径。对于一个塌陷,我们用(L1,R1,L2,R2,c)来描述,即对于主干路上L1到R1路径上的任意节点x,L2到R2路径上的任意节点y,都可以在c的时间内从x走到y。因为不知道自己所在的到底是哪个节点,所以要求出每个节点到目标节点K的最短距离。注意边是单向的

Solution

直接线段树优化建图显然不行,考虑发现一些性质。首先可以把一开始的树边也看作塌陷。显然对于一个塌陷,只有在dijkstra过程中第一个访问到的点才是有用的,也就是一个点用某条边更新完另一些点后这条边就废了,但是这样仍然不行,因为一个点可能被更新多次。考虑如何让每个点只被更新一次,我们可以把边也放入堆中,权值为最早到达这条边的点最短路+边权。每次取出堆顶,如果取出的是点,就用它更新边,如果取出的是边,就用来更新点。这样可以保证每条边和点都只被更新一次。如何实现呢?维护点可以用并查集,维护边可以用一个线段树+set。

Code

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=250010,Maxm=100010;
const int inf=2147483647;
int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
int n,m,k,fa[Maxn][18],dep[Maxn],in[Maxn],out[Maxn],dfn=0;
vector<int>edge[Maxn];
void dfs(int x,int ff)
{fa[x][0]=ff,dep[x]=dep[ff]+1;in[x]=++dfn;for(int i=1;(1<<i)<=dep[x];i++)fa[x][i]=fa[fa[x][i-1]][i-1];for(int i=0;i<edge[x].size();i++){int y=edge[x][i];if(y==ff)continue;dfs(y,x);}out[x]=dfn;
}
int LCA(int x,int y)
{if(dep[x]<dep[y])swap(x,y);for(int i=17;i>=0;i--)if((1<<i)<=dep[x]-dep[y])x=fa[x][i];if(x==y)return x;for(int i=17;i>=0;i--)if((1<<i)<=dep[x]&&fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];return fa[x][0];
}
struct Edge
{int l1,r1,l2,r2,c,p1,p2;bool del;Edge(int _l1=0,int _r1=0,int _l2=0,int _r2=0,int _c=0){l1=_l1,r1=_r1,l2=_l2,r2=_r2,c=_c;}
}e[(Maxn<<1)+Maxm];
int rt[Maxn];
int findrt(int x){return((rt[x]==x)?x:rt[x]=findrt(rt[x]));}
struct Seg{int l,r,lc,rc,mn,Fa;}tr[Maxn<<1];
int tot=0;
struct P
{int dep,id,o;P(int _dep,int _id,int _o){dep=_dep,id=_id,o=_o;}
};
bool operator<(P a,P b)
{if(a.dep!=b.dep)return a.dep<b.dep;if(a.id!=b.id)return a.id<b.id;
}
set<P>S[Maxn<<1];
void up(int x)
{int lc=tr[x].lc,rc=tr[x].rc;tr[x].mn=min(tr[lc].mn,tr[rc].mn);
}
void build(int l,int r)
{int x=++tot;tr[x].l=l;tr[x].r=r;tr[x].mn=inf;if(l==r)return;int mid=l+r>>1;tr[x].lc=tot+1,build(l,mid);tr[x].rc=tot+1,build(mid+1,r);tr[tr[x].lc].Fa=tr[tr[x].rc].Fa=x;
}
void Insert(int x,int p,int o,int id)
{if(tr[x].l==tr[x].r){S[x].insert(P(dep[e[id].p1],id,o));tr[x].mn=(*S[x].begin()).dep;return;}int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc;if(p<=mid)Insert(lc,p,o,id);else Insert(rc,p,o,id);up(x);
}
int u[100],lu;
void get(int x,int l,int r)
{if(tr[x].l==l&&tr[x].r==r){u[++lu]=x;return;}int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc;if(r<=mid)get(lc,l,r);else if(l>mid)get(rc,l,r);else get(lc,l,mid),get(rc,mid+1,r);
}
int ID;
void go(int x,int dep)
{if(tr[x].l==tr[x].r){ID=-1;while(!S[x].empty()){P t=(*S[x].begin());if(e[t.id].del)S[x].erase(t);else if(t.dep>=dep)break;else{ID=t.id;S[x].erase(t);break;}}if(S[x].empty())tr[x].mn=inf;else tr[x].mn=(*S[x].begin()).dep;while(x!=1){x=tr[x].Fa;up(x);}return;}int lc=tr[x].lc,rc=tr[x].rc;if(tr[lc].mn<dep)go(lc,dep);else go(rc,dep);
}
LL f[Maxn],g[(Maxn<<1)+Maxm];
struct Node
{int x,type;LL t;Node(int _x,int _type,LL _t){x=_x,type=_type,t=_t;}
};
bool operator<(Node a,Node b){return a.t>b.t;}
priority_queue<Node>q;
vector<int>H[Maxn];
void dijkstra()
{memset(f,63,sizeof(f));f[k]=0;rt[k]=fa[k][0];memset(g,63,sizeof(g));q.push(Node(k,0,0));while(!q.empty()){Node t=q.top();q.pop();int p=t.x;if(t.type==0){for(int i=0;i<H[p].size();i++){int tmp=H[p][i];if(e[tmp].del)continue;e[tmp].del=true;g[tmp]=f[p]+e[tmp].c;q.push(Node(tmp,1,g[tmp]));}lu=0;get(1,in[p],out[p]);for(int i=1;i<=lu;i++){int v=u[i];while(tr[v].mn<dep[p]){go(v,dep[p]);if(ID!=-1){e[ID].del=true;g[ID]=f[p]+e[ID].c;q.push(Node(ID,1,g[ID]));}else if(tr[v].mn>=dep[p])break;}}}else{int x=findrt(e[p].l2);while(dep[x]>=dep[e[p].p2]){f[x]=g[p];q.push(Node(x,0,f[x]));rt[x]=findrt(fa[x][0]);x=rt[x];}x=findrt(e[p].r2);while(dep[x]>=dep[e[p].p2]){f[x]=g[p];q.push(Node(x,0,f[x]));rt[x]=findrt(fa[x][0]);x=rt[x];}}}
}
int main()
{n=read(),m=read(),k=read();for(int i=0;i<=n;i++)rt[i]=i;for(int i=1;i<n;i++){int x=read(),y=read(),d=read();edge[x].push_back(y),edge[y].push_back(x);e[(i<<1)-1]=Edge(x,x,y,y,d);e[i<<1]=Edge(y,y,x,x,d);}for(int i=1;i<=m;i++){int l1=read(),r1=read(),l2=read(),r2=read(),c=read();e[((n-1)<<1)+i]=Edge(l2,r2,l1,r1,c);}dep[0]=-1;dfs(1,0);build(1,n);for(int i=1;i<=((n-1)<<1)+m;i++){e[i].p1=LCA(e[i].l1,e[i].r1);e[i].p2=LCA(e[i].l2,e[i].r2);H[e[i].p1].push_back(i);e[i].del=false;if(e[i].l1!=e[i].p1)Insert(1,in[e[i].l1],1,i);if(e[i].r1!=e[i].p1)Insert(1,in[e[i].r1],2,i);}dijkstra();for(int i=1;i<=n;i++)printf("%lld\n",f[i]);
}

[BZOJ]4699: 树上的最短路 特殊技巧的最短路相关推荐

  1. 针对常见的四种短路故障(单相接地短路,两相相间短路,两相接地短路,三相短路),可采取三种方法进行计算

    短路电流计算/ Matlab编程计算 针对常见的四种短路故障(单相接地短路,两相相间短路,两相接地短路,三相短路),可采取三种方法进行计算: 1.实用短路电流计算 2.对称分量法计算 3.节点导纳法计 ...

  2. 2021-10-26为什么单相短路和两相接地短路 的阻抗Zf的位置不同

    不对称短路分析时,附加阻抗在复合序网中的位置和大小,以下做出总结给出原因. 单相短路时,阻抗Zf,在复合序网中. 两相短路中 两相接地短路 通过上面的三个复合序网可以看出不同短路时,阻抗Zf在序网中的 ...

  3. BZOJ 2156 「国家集训队」星际探索(最短路)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2156 是 hydro 的 BZOJ ...

  4. BZOJ 4898 Luogu P3778 [APIO2017]商旅 (分数规划、最短路)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4898 (luogu)https://www.luogu.org/probl ...

  5. 对偶图 【BZOJ】1001: [BeiJing2006]狼抓兔子(对偶图+最短路)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001 可谓惨不忍睹,一下午就在调这题了. 很久以前看到这题是一眼最大流,看到n<=1000,我 ...

  6. UOJ #277 BZOJ 4739 [清华集训2016]定向越野 (计算几何、最短路)

    手动博客搬家: 本文发表于20181208 14:39:01, 原地址https://blog.csdn.net/suncongbo/article/details/84891710 哇它居然显示出图 ...

  7. Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路

    2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 647  Solved: 348 [Submit][S ...

  8. bzoj 1726: [Usaco2006 Nov]Roadblocks第二短路(A*第k短路)

    1726: [Usaco2006 Nov]Roadblocks第二短路 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1324  Solved: 627 ...

  9. bzoj 1665: [Usaco2006 Open]The Climbing Wall 攀岩(最短路)

    1665: [Usaco2006 Open]The Climbing Wall 攀岩 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 378  Solve ...

  10. BZOJ 1001[BeiJing2006]狼抓兔子 最小割转最短路

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...

最新文章

  1. java tomcat监控_java-jvisualvm远程监控tomcat
  2. JBOSS优化--比较有用的生产环境配置
  3. TweetLouder.com:在微博上找你喜好的乐队
  4. Redis源码剖析(十)简单动态字符串sds
  5. 为什么有那么多人选择“人工智能”,真的有那么好吗?
  6. java 怎么启动线程_线程如何正确的启动
  7. 关于控件开发的几点意见
  8. html5制作心路历程,一个真正0基础小白学习前端开发的心路历程
  9. java接口的关键字_java关键字-interface
  10. 决策树留一法python代码_西瓜书 第4章 决策树 读书笔记
  11. win11游戏窗口化如何设置 windows11游戏窗口化的设置方法
  12. Warning: To load an ES module, set “type“: “module“ in the package.json or use the .mjs extensi
  13. 苹果CMSv10最全系统标签,模板标签仿站必备
  14. 表白,游戏,跨年,各种节日祝福的link
  15. python中div是什么意思_python中divmod是什么
  16. CASS9.2启动提示连接数据库失败的解决方案
  17. 华为路由器静态路由基本配置
  18. Unlawfully wed 小小新娘 | 经济学人中英双语对照精读笔记
  19. ubuntu双系统引导梅花_Ubuntu Windows双系统和USB无线网卡安装的正确方法
  20. 数据挖掘之聚类分析(Cluster Analysis)

热门文章

  1. 在php中如何设置字体宋体,css怎么设置字体为宋体?
  2. (default-compile) on project datasource-demo: Fatal error compiling
  3. 盘点中国知名网络游戏公司
  4. AtCoder Beginner Contest 065(CD)
  5. 报错:Internal error XFS_WANT_CORRUPTED_GOTO at line 1635 of file fs/xfs/libxfs/xfs_alloc.c.
  6. 摄影曝光基础——光圈、快门、ISO
  7. android相机固定焦距,android - Android相机焦距和焦距不变 - 堆栈内存溢出
  8. 华为突破封锁,对标谷歌Dropout专利,开源自研算法Disout,多项任务表现更佳
  9. 两个tplink路由器有线桥接_新版TP-Link路由器有线桥接怎么设置?
  10. 微软关闭Win7所有服务器,微软公布Win7彻底退役时间 将于2020年终止所有支持