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
线段树建图优化最短路。
对于有向边:
两棵线段树*****
给个链接,说得挺清楚的,正确性自行yy。https://blog.youkuaiyun.com/lvzelong2014/article/details/79153621
无向图反过来再做一次。
有点着急的是算不来空间复杂度。。。老是mle
#include<bits/stdc++.h>
using namespace std;
const int Maxn=500005*log2(500005);
struct Edge{
int cnt,h[Maxn],w[Maxn],to[Maxn],next[Maxn];
inline void add(int x,int y,int z){
next[++cnt]=h[x];to[cnt]=y;w[cnt]=z;h[x]=cnt;
}
}e;
#define to e.to[p]
int n,m,s;
int cnt,p[2][Maxn];
struct SegMent{
struct tree{
int l,r,ls,rs;
}t[Maxn];int root[2];
inline void link(int x,int l,int r,int y,int v,int cmd){
if(t[x].l>r||t[x].r<l)return ;
if(l<=t[x].l&&t[x].r<=r){
return cmd?e.add(y,x,v):e.add(x,y,v),void();
}
link(t[x].ls,l,r,y,v,cmd),link(t[x].rs,l,r,y,v,cmd);
}
inline void build(int &x,int l,int r,int cmd){
t[x=++cnt]=(tree){l,r,0,0};
int mid=l+r>>1;
if(l==r)return p[cmd][mid]=x,void();
build(t[x].ls,l,mid,cmd),build(t[x].rs,mid+1,r,cmd);
if(cmd){
e.add(x,t[x].ls,0),e.add(x,t[x].rs,0);
}else {
e.add(t[x].ls,x,0),e.add(t[x].rs,x,0);
}
}
}seg;
struct Dijkstra{
struct HeapNode{
int x,dist;
bool operator <(const HeapNode&A) const {
return dist>A.dist;
}
};
int dist[Maxn];
bool vst[Maxn];
inline void dijkstra(){
priority_queue<HeapNode>Q;
memset(vst,0,sizeof(vst));
// for(int i=1;i<=n;++i)dist[p[1][i]]=0x3f3f3f3f;
memset(dist,63,sizeof(dist));
Q.push((HeapNode){p[1][s],dist[p[1][s]]=0});
while(!Q.empty()){
HeapNode tp=Q.top();Q.pop();
if(vst[tp.x])continue;
vst[tp.x]=1;
for(int p=e.h[tp.x];p;p=e.next[p])if(dist[to]>dist[tp.x]+e.w[p]){
dist[to]=dist[tp.x]+e.w[p];
Q.push((HeapNode){to,dist[to]});
}
}
}
}dij;
int main(){
// cout<<sizeof(dij)/1024/1024+sizeof(e)/1024/1024+sizeof(seg)/1024/1024;
scanf("%d%d%d",&n,&m,&s);
seg.build(seg.root[0],1,n,0);
seg.build(seg.root[1],1,n,1);
// for(int i=1;i<=n;++i)cout<<p[1][i]<<" ";
for(int i=1;i<=n;++i)e.add(p[1][i],p[0][i],0);
for(int i=1;i<=m;++i){
int a,b,c,d;scanf("%d%d%d%d",&a,&b,&c,&d);
++cnt;seg.link(seg.root[0],a,b,cnt,0,0);
++cnt;seg.link(seg.root[1],c,d,cnt,0,1);
e.add(cnt-1,cnt,1);
++cnt;seg.link(seg.root[0],c,d,cnt,0,0);
++cnt;seg.link(seg.root[1],a,b,cnt,0,1);
e.add(cnt-1,cnt,1);
}
// cout<<23333333333<<"\n";
dij.dijkstra();
for(int i=1;i<=n;++i)cout<<dij.dist[p[1][i]]<<"\n";
return 0;
}