Description

给出一个$n$个点$m$条边的无向图,$n$个点的编号从$1-n$,定义源点为$1$.

定义最短路树如下:从源点$1$经过边集$T$到任意一点$i$有且仅有一条路径,且这条路径是整个图$1$到$i$的最短路径,边集$T$构成最短路树.

给出最短路树,求对于除了源点$1$外的每个点$i$,求最短路,要求不经过给出的最短路树上的$1$到$i$的路径的最后一条边.

Input

第一行包含两个数$n$和$m$,表示图中有$n$个点和$m$条边.

接下来$m$行,每行有四个数$a_i,b_i,l_i,t_i$,表示图中第$i$条边连接$a_i$和$b_i$权值为$l_i,t_i$为$1$表示这条边是最短路树上的边,$t_i$为$0$表示不是最短路树上的边.

Output

输出$n-1$个数,第$i$个数表示从$1$到$i+1$的要求的最短路.无法到达输出$-1$.

Sample Input

5 9
3 1 3 1
1 4 2 1
2 1 6 0
2 3 4 0
5 2 3 0
3 2 2 1
5 3 1 1
3 5 2 0
4 5 4 0

Sample Output

6 7 8 5

HINT

$n\;\leq\;4000,m\;\leq\;100000,1\;\leq\;l_i\;\leq\;100000$

Solution

对于一条不在最短路树上的边$e[u][v]$,显然它只对$(u,v)$上除了$lca(u,v)$之外的点有影响.

对于$(lca(u,v),v)$上除了$lca(u,v)$之外的点$k$,一条可行路径为$1->u->v->k$.

($lca(u,v)$不合法,不属于$(u,v)$的点显然更劣.)

设$dis[i]$为最短路树中$(1,i)$的长度,

则这条可行路径$1->u->v->k$长度为$dis[u]+e[u][v]+dis[v]-dis[k]$.

$dis[k]$为定值,则要求合法的最小的$dis[u]+e[u][v]+dis[v]$.

这个可以用树链剖分+线段树维护.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 4005
#define M 100005
#define INF 900000000
using namespace std;
struct linetree{int l,r,m;
}lt[M];
struct graph{int nxt,to,w;
}e[M<<1];
struct line{int l,r,w;
}a[M];
int g[N],dis[N],n,m,tot,cnt;
int f[N],p[N],dep[N],siz[N],son[N],top[N];
inline void addedge(int x,int y,int w){e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;e[cnt].w=w;
}
inline void dfs1(int u){int m=0;siz[u]=1;for(int i=g[u];i;i=e[i].nxt)if(!dep[e[i].to]){f[e[i].to]=u;dep[e[i].to]=dep[u]+1;dis[e[i].to]=dis[u]+e[i].w;dfs1(e[i].to);siz[u]+=siz[e[i].to];if(siz[e[i].to]>m){son[u]=e[i].to;m=siz[e[i].to];}}
}
inline void dfs2(int u,int tp){top[u]=tp;p[u]=++cnt;if(son[u]) dfs2(son[u],tp);for(int i=g[u];i;i=e[i].nxt)if(e[i].to!=f[u]&&e[i].to!=son[u])dfs2(e[i].to,e[i].to);
}inline void build(int u,int l,int r){lt[u].l=l;lt[u].r=r;lt[u].m=INF;if(lt[u].l<lt[u].r){int mid=(lt[u].l+lt[u].r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);}
}
inline void cover(int u,int l,int r,int k){if(lt[u].l>=l&&lt[u].r<=r){lt[u].m=min(lt[u].m,k);}else if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1;int mid=(lt[u].l+lt[u].r)>>1;lt[lef].m=min(lt[u].m,lt[lef].m);lt[rig].m=min(lt[u].m,lt[rig].m);if(l<=mid) cover(lef,l,r,k);if(r>mid) cover(rig,l,r,k);}
}
inline int ask(int u,int x){if(lt[u].l<lt[u].r){int lef=u<<1,rig=u<<1|1;int mid=(lt[u].l+lt[u].r)>>1;lt[lef].m=min(lt[u].m,lt[lef].m);lt[rig].m=min(lt[u].m,lt[rig].m);if(x<=mid) return ask(lef,x);return ask(rig,x);}return lt[u].m;
}
inline void cov(int u,int v,int k){int t;while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]){t=u;u=v;v=t;}cover(1,p[top[u]],p[u],k);u=f[top[u]];}if(p[u]>p[v]){t=u;u=v;v=t;}if(u!=v) cover(1,p[u]+1,p[v],k);
}
inline void Aireen(){scanf("%d%d",&n,&m);for(int i=1,j,k,w,t;i<=m;++i){scanf("%d%d%d%d",&j,&k,&w,&t);if(t){addedge(j,k,w);addedge(k,j,w);}else{a[++tot].l=j;a[tot].r=k;a[tot].w=w;}}dep[1]=1;dfs1(1);cnt=0;dfs2(1,1);build(1,1,n);m=tot;for(int i=1;i<=m;++i)cov(a[i].l,a[i].r,a[i].w+dis[a[i].l]+dis[a[i].r]);for(int i=2,k;i<=n;++i){k=ask(1,p[i]);if(k==INF) printf("-1 ");else printf("%d ",k-dis[i]);}
}
int main(){freopen("dis.in","r",stdin);freopen("dis.out","w",stdout);Aireen();fclose(stdin);fclose(stdout);return 0;
}

转载于:https://www.cnblogs.com/AireenYe/p/6219996.html

[bzoj3694]最短路相关推荐

  1. bzoj3694:最短路(最短路树+并查集)

    3694:最短路 时间限制: 1000 ms 内存限制: 262144 KB 题目描述 给出一个 n n n个点m" role="presentation" style= ...

  2. [C] [最短路] 只有5行的算法:Floyd-Warshall

    终于学到求最短路了,终于来到我最喜欢的算法--Floyd-Warshall了!今天还有点小激动呢! 我喜欢它,当然是因为它逻辑十分简单咯!真的只有5行诶! Floyd-Warshall算法 题目描述 ...

  3. BZOJ4152 AMPPZ2014 The Captain(最短路)

    事实上每次走到横坐标或纵坐标最接近的点一定可以取得最优方案.于是这样连边跑最短路就可以了. #include<iostream> #include<cstdio> #inclu ...

  4. Codeforces.1051F.The Shortest Statement(最短路Dijkstra)

    题目链接 先随便建一棵树. 如果两个点(u,v)不经过非树边,它们的dis可以直接算. 如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案. 所以枚 ...

  5. BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)

    Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2343  Solved: 1266 [Submit][Status][Discuss] Descrip ...

  6. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集

    题目链接 题意:就是给你一堆关系,看能不能排出个确定的顺序 做法: 1. 拓扑排序+并查集 应该很容易想到的一种思路,大于小于建立单向边.对于相等的呢,就把他们缩成一个点.就用并查集缩成一个点就行了 ...

  7. E:By Elevator or Stairs? CF595 DP最短路

    题目链接 比赛的时候一看,这不是最短路吗,然后敲了一个最短路. 然后比赛完发现大家基本都写的dp,我真是个憨憨,dp3行 最短路就建个简单的图,dp就是从上一维转化过来就是了 优秀的dp: //#pr ...

  8. The Shortest Statement CodeForces - 1051F LCA+最短路

    太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...

  9. JZOJ #4722 跳楼机 (最短路模型的完美转化)

    题目描述: 给出$h,x,y,z$,求在$h$以内,$x,y,z$可以凑出多少个不同的数.$(1\leq{h}\leq{10^{18}},1\leq{x,y,z}\leq{10^5})$ 解题思路: ...

最新文章

  1. Object-C 打开工程,选择模拟起时,提示no scheme
  2. Linux部分系统IO函数
  3. VTK:AngleWidget2D用法实战
  4. SAP CRM中间件下载时数据库表CRMATAB为空的处理方法
  5. mysql5.7.19不好用_Mysql 5.7.19 免安装版遇到的坑(收藏)
  6. 产品经理如何应对一句话需求
  7. 盘点 GitHub 上那些沙雕项目
  8. Failed to start component [StandardEngine[Catalina].StandardHost[localhost].错误解决方案
  9. 3 矩阵运算_FlyAI小课堂:小白学PyTorch(11) 常见运算详解
  10. java weblogic 下载_JAVA_weblogic企业级技术 PDF 下载
  11. Android GMS 包。 GOOGLE play
  12. Matches UVA - 11375 递推+大数 Ingenuous Cubrency UVA - 11137 递推
  13. 【快应用】如何去掉快应用页面的menuBar
  14. 团队成员筛选的核心秘档:三否三拒三不动
  15. 南宁计算机职称考试网,南宁人事考试职称网
  16. android仿网易云音乐引导页、仿书旗小说Flutter版、ViewPager切换、风扇叶片效果等源码...
  17. 半年经验Java面试准备
  18. Revit完整案例教程
  19. MATLAB中的CVX包使用中的错误:Cannot perform the operation: {convex} .* {convex}
  20. 【mysql】获取指定日期是当年第几周,指定日期所在周的开始和结束日期

热门文章

  1. asp.net MVC遇到的问题
  2. mvdr波束形成原理_有了波束赋形这个5G黑科技,让你畅享飞一样的网速
  3. lh服最新服务器,LH服12月1日开发更新 着重提升服务器稳定性与职业bug修复
  4. Android NDK开发之 Android系统开发中LOG的使用
  5. 数据通信基础(面试必备)
  6. PAT (Basic Level) Practice1030 完美数列
  7. Linux嵌入式_详解从原理图到数据手册解析PWM蜂鸣器实现
  8. Windows核心编程_异型窗口
  9. 常用Linux 服务器命令--各种性能指标命令
  10. zabbix-proxy+cacti+nagios基本安装配置