[bzoj3694]最短路
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&<[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;
}
[bzoj3694]最短路的更多相关文章
- bzoj3694最短路
		
bzoj3694最短路 Description 给出一个n个点m条边的无向图,n个点的编号从1~n,定义源点为1.定义最短路树如下:从源点1经过边集T到任意一点i有且仅有一条路径,且这条路径是整个图1 ...
 - [bzoj3694]最短路_树链剖分_线段树
		
最短路 bzoj-3694 题目大意:给你一个n个点m条边的无向图,源点为1,并且以点1为根给出最短路树.求对于2到n的每个点i,求最短路,要求不经过给出的最短路树上的1到i的路径上的最后一条边. 注 ...
 - bzoj3694: 最短路(树链剖分/并查集)
		
bzoj1576的帮我们跑好最短路版本23333(双倍经验!嘿嘿嘿 这题可以用树链剖分或并查集写.树链剖分非常显然,并查集的写法比较妙,涨了个姿势,原来并查集的路径压缩还能这么用... 首先对于不在最 ...
 - 「BZOJ3694」「FJ2014集训」最短路
		
「BZOJ3694」「FJ2014集训」最短路 首先树剖没得说了,这里说一下并查集的做法, 对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t ...
 - 最短路 BZOJ3694 树链剖分+线段树
		
分析: 树剖裸题,[Usaco2009 Jan]安全路经Travel 的简化版 剖开最短路树,遍历每一条没在最短路树上的边. 这种情况下,有且仅有u到v路径上,出来lca之外的点能够通过这条边到达,并 ...
 - [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)
		
[BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...
 - bzoj1001--最大流转最短路
		
http://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路:这应该算是经典的最大流求最小割吧.不过题目中n,m<=1000,用最大流会TLE, ...
 - 【USACO 3.2】Sweet Butter(最短路)
		
题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...
 - Sicily 1031: Campus (最短路)
		
这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...
 
随机推荐
- jquery两个滚动条样式
			
jquery两个滚动条样式 点击下载
 - P3369 【模板】普通平衡树(Treap/SBT)
			
题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(若有多个相同的数,因输出最小的排名) 查询 ...
 - Openjudge 1.13-40 提取数字串按数值排序
			
40:提取数字串按数值排序 查看 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个字符串,请将其中的所有数字串提取,并将每个数字串作为整数看待(假设可以用int 表示),按从 ...
 - weblogic 10.x 上开发restful服务
			
之前已经学习过 利用JAX-RS快速开发RESTful 服务,当时是jboss环境,如果原封不动的迁移到weblogic 10.x 版本,会杯具的发现应用启动失败,需要做些小调整: 项目结构如下: 需 ...
 - Oracle:ODP.NET Managed 小试牛刀
			
“ODP.NET Managed”发布已经有一段时间了,近期正好有一个新项目,想尝试用一下,参考园子里的文章:<.NET Oracle Developer的福音——ODP.NET Managed ...
 - 基于SignalR的小型IM系统
			
这个IM系统真是太轻量级了,提供的功能如下: 1.聊天内容美化 2.用户上下线提示 3.心跳包检测机制 4.加入用户可群聊 下面来一步一步的讲解具体的制作方法. 开篇准备工作 首先,巧妇难为无米之炊, ...
 - Redirect和Dispatcher 区别
			
使用forward是服务跳转,浏览器不知道它所请求的具体资源来源,浏览器的地址栏不会变:使用redirect,服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL ...
 - 拿到腾讯实习offer的前后小事
			
一.前言 本文应该算不上是面经,仅仅是自己近期一路走过的些许琐碎小事,欢迎园友吐槽,但是不要太凶残哦. 二.旧年小事 去年11月底,从上海实习公司请假回校参加研究生毕业论文开题答辩,在校忙碌了一段时间 ...
 - 浅析WPhone、Android的Back与Home键
			
浅析WPhone.Android的Back与Home键 背景 本人一直在用诺基亚手机(目前是Nokia 925,Windows Phonre 8.1),在界面设计.应用多样性等方面没少受身边Andro ...
 - Javascript 模块化开发上线解决方案
			
最近又换部门了,好频繁地说...于是把这段时间搞的小工具们简单整理了一下,作了一个小的总结.这次用一个简单业务demo来向大家介绍一下Javascript模块化开发的方式和自动化合并压缩的一些自己的处 ...