新技能get✔。

线段树优化建边主要是针对一类连续区间和连续区间之间建边的题,建边非常的优秀。。


这题中,每次要求$[l1,r1]$每一点向$[l2,r2]$每一点建无向边,然后单元最短路。


暴力建边,边数$O(n^2m)$,时空双炸。

优化一点的建边,对于一个区间的点,把他们统一向一个虚点连零边,再从这个虚点向另一个区间每一个点连一条带权边。这样,每一条路径都是可以通过这个来表示的。边数$O(nm)$,仍然不行。

然后,采用线段树的优秀的“将区间拆分成不超过$\log n$个小区间”的性质,对于$n$个点,建两颗线段树$A,B$,$A$称作入树,$B$称作出树。他们的叶子就是所有的$n$个点,上面的非叶点就是区间。。(先假设是单向的边)然后,对于一次区间向另一区间的连边,从出树$B$拆分出来的对应的$\log n$个区间代表的点分别向一个新开的虚点连一条有向0边,再从这个虚点向入树$A$对应的另一个区间拆分的若干小区间点连带权边,这样实现了区间连边。但是,这只是区间整体连边了,还要保证点与点连通,只要把出树$B$每个点从孩子向父亲连有向0边,入树$A$每个点从父亲向孩子连有向0边,就表示一个点通过“爬”到一个区间点,走过虚点,在下来走到另外一个目标点这样一个过程。最后,走进入树后,为了可以继续走,从$A$向$B$的每一个代表相同区间的点连0边,表示再过去。

有一个dalao的图可能会解释的非常清晰。。附上地址

线段树优化建边大致就是这个原理。然后直接从底层叶子开始为源点跑dij就行了。

然后个人觉得很多代码很繁。。偶尔看到一种写法,对每个点编一个号,把AB两树底层叶子编号直接合并成一个,省去了两树之间的相互建边。。这样码量就小很多了。具体还是看代码。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=5e5+;
int n,m,s,cnt;
struct thxorz{
int head[N*],nxt[N*],to[N*],w[N*],tot;
inline void add(int x,int y,int z){to[++tot]=y,nxt[tot]=head[x],head[x]=tot,w[tot]=z;}
}G;
struct SGT{
int id[N<<];
#define lc i<<1
#define rc i<<1|1
void build(int i,int L,int R,int dir){
if(L==R){id[i]=L;return;}
id[i]=++cnt;int mid=L+R>>;//dbg2(i,cnt),dbg2(L,R);
build(lc,L,mid,dir),build(rc,mid+,R,dir);
if(!dir)G.add(id[i],id[lc],),G.add(id[i],id[rc],);
else G.add(id[lc],id[i],),G.add(id[rc],id[i],);
}
void update(int i,int L,int R,int ql,int qr,int dir){
if(ql<=L&&qr>=R){dir?G.add(cnt,id[i],):G.add(id[i],cnt,);return;}
int mid=L+R>>;
if(ql<=mid)update(lc,L,mid,ql,qr,dir);
if(qr>mid)update(rc,mid+,R,ql,qr,dir);
}
}A,B;
priority_queue<pii,vector<pii>,greater<pii> > pq;
int dis[N*];
#define y G.to[j]
inline void dij(){
memset(dis,0x3f,sizeof dis);pq.push(make_pair(dis[s]=,s));
while(!pq.empty()){
int d=pq.top().first,x=pq.top().second;pq.pop();
if(dis[x]^d)continue;
for(register int j=G.head[x];j;j=G.nxt[j])if(MIN(dis[y],d+G.w[j]))pq.push(make_pair(dis[y],y));
}
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
cnt=read(n),read(m),read(s);
A.build(,,n,),B.build(,,n,);
for(register int i=,l1,r1,l2,r2;i<=m;++i){
read(l1),read(r1),read(l2),read(r2);
++cnt,B.update(,,n,l2,r2,),A.update(,,n,l1,r1,);
++cnt,B.update(,,n,l1,r1,),A.update(,,n,l2,r2,);
}
dij();
for(register int i=;i<=n;++i)printf("%d\n",dis[i]);
return ;
}

不过,这题鉴于全是0/1边,所以直接一个0/1BFS就可以线性解决了。。并没有快多少可能是deque的锅。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=5e5+;
int n,m,s,cnt;
struct thxorz{
int head[N*],nxt[N*],to[N*],w[N*],tot;
inline void add(int x,int y,int z){to[++tot]=y,nxt[tot]=head[x],head[x]=tot,w[tot]=z;}
}G;
struct SGT{
int id[N<<];
#define lc i<<1
#define rc i<<1|1
void build(int i,int L,int R,int dir){
if(L==R){id[i]=L;return;}
id[i]=++cnt;int mid=L+R>>;//dbg2(i,cnt),dbg2(L,R);
build(lc,L,mid,dir),build(rc,mid+,R,dir);
if(!dir)G.add(id[i],id[lc],),G.add(id[i],id[rc],);
else G.add(id[lc],id[i],),G.add(id[rc],id[i],);
}
void update(int i,int L,int R,int ql,int qr,int dir){
if(ql<=L&&qr>=R){dir?G.add(cnt,id[i],):G.add(id[i],cnt,);return;}
int mid=L+R>>;
if(ql<=mid)update(lc,L,mid,ql,qr,dir);
if(qr>mid)update(rc,mid+,R,ql,qr,dir);
}
}A,B;
deque<pii> q;
int dis[N*];
#define y G.to[j]
inline void dij(){
memset(dis,0x3f,sizeof dis);q.push_back(make_pair(dis[s]=,s));
while(!q.empty()){
int d=q.front().first,x=q.front().second;q.pop_front();
if(d^dis[x])continue;
for(register int j=G.head[x];j;j=G.nxt[j])if(MIN(dis[y],d+G.w[j]))
G.w[j]?q.push_back(make_pair(dis[y],y)):q.push_front(make_pair(dis[y],y));
}
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
cnt=read(n),read(m),read(s);
A.build(,,n,),B.build(,,n,);
for(register int i=,l1,r1,l2,r2;i<=m;++i){
read(l1),read(r1),read(l2),read(r2);
++cnt,B.update(,,n,l2,r2,),A.update(,,n,l1,r1,);
++cnt,B.update(,,n,l1,r1,),A.update(,,n,l2,r2,);
}
dij();
for(register int i=;i<=n;++i)printf("%d\n",dis[i]);
return ;
}

总结:区间建边,线段树。。

BZOJ3073 [Pa2011]Journeys[最短路—线段树优化建边]的更多相关文章

  1. [bzoj3073] Journeys 题解(线段树优化建图)

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

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

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

  3. BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS

    BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N ...

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

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

  5. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  6. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  7. 洛谷3783 SDOI2017 天才黑客(最短路+虚树+边转点+线段树优化建图)

    成功又一次自闭了 怕不是猪国杀之后最自闭的一次 一看到最短路径. 我们就能推测这应该是个最短路题 现在考虑怎么建图 根据题目的意思,我们可以发现,在本题中,边与边之间存在一些转换关系,但是点与点之间并 ...

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

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

  9. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

随机推荐

  1. Linux上,最常用的一批命令解析(10年精选)

    Linux这么多命令,通常会让初学者望而生畏.下面是我结合日常工作,以及在公司的内部培训中,针对对Linux不是很熟悉的同学,精选的一批必须要搞懂的命令集合.任何一个命令其实都是可以深入的,比如tai ...

  2. JavaSE基础(七)--Java流程控制语句之switch case 语句

    Java switch case 语句 switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支. 语法 switch case 语句语法格式如下: switch(exp ...

  3. Nuxt.js入门学习

    Nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).再直白点说,就是Vue.js原来是开发SPA(单页应用)的,但是随着技术的普及,很多人想用Vue开发多页应用, ...

  4. storm drpc分布式本地和远程调用模式讲解

    一.drpc 的介绍 1.rpc RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 2.drpc drp ...

  5. 【Funny Things】001——QQ循环发送消息

    借用Java的Robot类库中的键鼠模拟的方法,执行这个操作,首先切换到QQ界面,然后循环粘贴,回车发送消息. package newtest; import java.awt.*; import j ...

  6. Qt Pro相关

      Qt项目pro文件相关知识总结和记录 pro文件中使用相对路径需要注意的地方 INCLUDE_PATH 后接的路径./代表的是pro所在目录 LIBS 后接的./是可执行文件所在的目录,该目录会被 ...

  7. [DEBUG] Spring boot前端html无法下载示例文件

    更新:原方法打jar包的时候是可以的,后来我打war包之后下载的文件就是0字节.尴尬:) 所以现在更换一种方法,然后打war包.在服务器已测试成功. 前端不需要改变,只需要更改controller: ...

  8. Pebbles HDU 2167

    Pebbles HDU 2167 大意:给定一个N*N的方格,让你在里面取出一些数使其和最大,要求每一个数不能与其相邻的8个数同时取出. 思路:和炮兵阵地那一题有点像,但我们只需要考虑上一行的情况,这 ...

  9. 整体二分(模板二)动态区间第K大

    这才是更一般的二分写法--HDU5412 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #include <cstdio>// ...

  10. python并发编程之多进程(实践篇)

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了multiproce ...