BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS
BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS
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 41 2 4 5
5 5 4 4
1 1 3 3
Sample Output
11
2
0
1 有一个朴素的方法:对(a,b)中的点对一个新建节点连边边权为0,对另一个新建节点连边权为1,另一个新建节点向(c,d)中的所有节点连边。 用线段树优化一下: 开两个线段树A,B,其中A中的节点向父亲连边,B中节点向儿子连边。B中叶子向A中叶子连边。 然后把(a,b)中的点替换成线段树上的log个节点,和上面的连边方法相同。 跑最短路即可,由于边权是0,1可以BFS上去。 代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 500050 #define M 4000050 int Q[M],tot,l,r,ls[N<<3],rs[N<<3]; int head[M][2],to[M<<2][2],nxt[M<<2][2],cnt,idx ,n,m,a[N<<3],dis[M],rta,rtb,b[N<<3]; inline void add(int u,int v,int w) { to[++cnt][w]=v; nxt[cnt][w]=head[u][w]; head[u][w]=cnt; } void build(int l,int r,int &p,int flg) { p=++tot; if(l==r) { if(!flg) idx[l]=p; else b[l]=p; return ; } int mid=(l+r)>>1; build(l,mid,ls[p],flg); build(mid+1,r,rs[p],flg); if(!flg) { add(ls[p],p,0); add(rs[p],p,0); }else { add(p,ls[p],0); add(p,rs[p],0); } } void update(int l,int r,int x,int y,int p) { if(x<=l&&y>=r) { a[++a[0]]=p; return ; } int mid=(l+r)>>1; if(x<=mid) update(l,mid,x,y,ls[p]); if(y>mid) update(mid+1,r,x,y,rs[p]); } void link(int x,int y,int z,int w) { tot++; update(1,n,x,y,rta); int i; for(i=1;i<=a[0];i++) add(a[i],tot,0); a[0]=0; tot++; add(tot-1,tot,1); update(1,n,z,w,rtb); for(i=1;i<=a[0];i++) add(tot,a[i],0); a[0]=0; } void dfs(int x,int y) { if(dis[x]) return ; dis[x]=y; Q[r++]=x; int i; for(i=head[x][0];i;i=nxt[i][0]) dfs(to[i][0],y); } int main() { int S;int i,x,y,z,w; scanf("%d%d%d",&n,&m,&S); rta=0,rtb=0; build(1,n,rta,0); build(1,n,rtb,1); for(i=1;i<=n;i++) add(b[i],idx[i],0); for(i=1;i<=m;i++) { scanf("%d%d%d%d",&x,&y,&z,&w); link(x,y,z,w); link(z,w,x,y); } dfs(idx[S],1); while(l<r) { x=Q[l++];y=dis[x]+1; for(i=head[x][1];i;i=nxt[i][1]) dfs(to[i][1],y); } for(i=1;i<=n;i++) { printf("%d\n",dis[idx[i]]-1); } }
- [线段树建图 bfs] BZOJ 3073 [Pa2011]Journeys
- bzoj 3073: [Pa2011]Journeys
- 【线段树优化建图+最短路】BZOJ3073 [Pa2011]Journeys
- bzoj 3073: [Pa2011]Journeys 线段树优化建图+堆优化dij
- BZOJ[3073][Pa2011]Journeys 线段树优化建图+Dijkstra堆优化
- 【BZOJ3073】[Pa2011]Journeys 线段树+堆优化Dijkstra
- bzoj 3073: [Pa2011]Journeys -- 线段树优化最短路
- BZOJ 3073: [Pa2011]Journeys 线段树优化最短路
- [bzoj3073][Pa2011]Journeys 线段树优化建边的最短路
- BZOJ 3073 [Pa2011]Journeys 最短路 线段树优化建图
- 【PA2011】【BZOJ3073】Journeys
- 3073: [Pa2011]Journeys|线段树|BFS
- 【线段树优化建图+BFS】BZOJ3073(Pa2011)[Journeys]题解
- 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
- BZOJ3070 : [Pa2011]Prime prime power 质数的质数次方
- 【bzoj 3073】Journeys(线段树优化建图)
- 【PA2011】【BZOJ3069】Hard Choice 艰难的选择
- 【BZOJ】4130: [PA2011]Kangaroos【KD树——最长连续1的子段长度】
- BZOJ3073 - [PA2011]Journeys
- BZOJ3073 : [Pa2011]Journeys