Description

Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路。N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a,b),(c,d)表示,对于任意两个国家x,y,如果a<=x<=b,c<=y<=d,那么在xy之间建造一条道路。Seter保证一条道路不会修建两次,也保证不会有一个国家与自己之间有道路。
Seter好不容易建好了所有道路,他现在在位于P号的首都。Seter想知道P号国家到任意一个国家最少需要经过几条道路。当然,Seter保证P号国家能到任意一个国家。
 
注意:可能有重边

Input

第一行三个数N,M,P。N<=500000,M<=100000。
后M行,每行4个数A,B,C,D。1<=A<=B<=N,1<=C<=D<=N。

Output

N行,第i行表示P号国家到第i个国家最少需要经过几条路。显然第P行应该是0。

Sample Input

5 3 4
1 2 4 5
5 5 4 4
1 1 3 3

Sample Output

1
1
2
0
1
 

可以看出来难点在于建图,建完后一个堆优化dj就搞定

排除最朴素的循环建边,不难想到一种较为优化的方式:

将$(a,b)$的点向虚拟节点$p_1$连一条边权为0的边,再将$p_1$与$p_2$相连,边权为1,最后将$p_2$连到$(c,d)$边权为0。

但这还不是最优的方法,事实上,建图的过程完全可以用线段树优化。

由于建图要对区间进行操作,所以可以想到线段树(强行扯上关系)

建立A树与B树,A树的非叶子节点向父亲连边,B树的非叶子节点向儿子连边,边权为0;(两树的叶节点对应真实节点,其余为虚构点)

B树的叶节点向A树叶节点连边,

当进行区间连边操作时,找到区间在A线段树上的位置,把这部分向虚点连0权边,再连1权边到另一虚点,再连到B上,

没错,就是我们一开始考虑的小优化。

这里的线段树可以动态开点,注意跑dj时要用映射后的点编号。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define pa pair<int,int>
const int N=,M=;
int n,m,to[M<<],nxt[M<<],len[M<<],head[M],tot,dis[M],s,v[M];
int ls[N<<],rs[N<<],type,key[N<<],root1,root2;
priority_queue<pa> q;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>'')
{if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')
{x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
void add(int x,int y,int z)
{
to[++tot]=y;
len[tot]=z;
nxt[tot]=head[x];
head[x]=tot;
}
void build(int &k,int l,int r,int val)
{
k=++type;
if(l==r)
{
if(val)key[l]=k;
return ;
}
int mid=l+r>>;
build(ls[k],l,mid,val);
build(rs[k],mid+,r,val);
if(val)add(ls[k],k,),add(rs[k],k,);
else add(k,ls[k],),add(k,rs[k],);
}
void pre(int l,int r,int x,int y)
{
if(l==r)
{
add(y,x,);
return ;
}
int mid=l+r>>;
pre(l,mid,ls[x],ls[y]);
pre(mid+,r,rs[x],rs[y]);
}
void update(int S,int T,int l,int r,int x,int y,int val)
{
if(S<=l&&r<=T)
{
if(val)add(x,y,);
else add(y,x,);
return ;
}
int mid=l+r>>;
if(S<=mid)update(S,T,l,mid,ls[x],y,val);
if(T>mid)update(S,T,mid+,r,rs[x],y,val);
}
void link(int a,int b,int c,int d)
{
update(a,b,,n,root1,++type,);
add(type,type+,);
update(c,d,,n,root2,++type,);
}
void Dj(int st)
{
memset(dis,0x3f,sizeof(dis));
pa tmp=make_pair(,key[st]);
q.push(tmp);
dis[key[st]]=;
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(v[x])continue;
v[x]=;
for(int i=head[x];i;i=nxt[i])
{
if(dis[to[i]]>dis[x]+len[i])
{
dis[to[i]]=dis[x]+len[i];
q.push(make_pair(-dis[to[i]],to[i]));
}
}
}
}
int main()
{
n=read();m=read();s=read();
build(root1,,n,);build(root2,,n,);
pre(,n,root1,root2); for(int i=;i<=m;i++)
{
int a=read(),b=read(),c=read(),d=read();
link(a,b,c,d);link(c,d,a,b);
}
Dj(s);
for(int i=;i<=n;i++)
printf("%d\n",dis[key[i]]);
return ;
}

[bzoj3073] Journeys 题解(线段树优化建图)的更多相关文章

  1. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  2. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  3. 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

  4. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  5. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  6. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

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

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

  8. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  9. bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...

  10. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

随机推荐

  1. CDN(Content Delivery Network)内容分发网络

    CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节 ...

  2. windows10下安装Mysql 5.6(zip格式安装包)

    5.6的安装包是一个zip文件,里面包含了data(有表空间文件和日志文件),bin等文件夹.不同于以往的只需要双击安装.msi就行了.因此,在此记录下安装包是.zip时的安装步骤. 1下载 进htt ...

  3. if语句里面continue和break的区别

    break:结束整个循环体 continue:结束本次循环 代码说明: public static void main(String[] args) { int x=0; while(x++ < ...

  4. mysql数据权限操作

    1.创建新用户 通过root用户登录之后创建 >> grant all privileges on *.* to testuser@localhost identified by &quo ...

  5. MySQL教程和使用手册

    MySQL 教程 MySQL 教程.MySQL 安装.MySQL 管理.MySQL PHP 语法.MySQL 连接.MySQL 创建数据库.MySQL 删除数据库.MySQL 选择数据库.MySQL ...

  6. HBase 入门之数据刷写(Memstore Flush)详细说明

    接触过 HBase 的同学应该对 HBase 写数据的过程比较熟悉(不熟悉也没关系).HBase 写数据(比如 put.delete)的时候,都是写 WAL(假设 WAL 没有被关闭) ,然后将数据写 ...

  7. java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...

  8. ArcGis基础——设置图层可选状态

    在ArcMap的图层列表上右键,可以设置“仅本图层可选”. 那么,如何设置回多个或者全部图层可选状态呢? 1.在ArcMap的菜单栏找到 自定义——自定义模式——选择——设置可选图层. 2.将“设置可 ...

  9. expect的模式

    expect的模式其实就是对话模式: expect    # 期望什么 send      # 我给你什么 比如: expect "password: "    # 碰到什么了 s ...

  10. css点击按钮,依次动态展开面板动画效果

    <a href="#one">按钮1</a> <a href="#two">按钮2</a> <a href ...