BZOJ3073 Journeys

版权声明: https://blog.csdn.net/DancingZ/article/details/82806012

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.csdn.net/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;
}

猜你喜欢

转载自blog.csdn.net/DancingZ/article/details/82806012