BZOJ 3073: [Pa2011]Journeys
Description
\(n\)个点,每次在\([a,b]\)到\([c,d]\)的点,分别连边 \(n\leqslant 5\times 10^5,m\leqslant 10^5\).
Solution
最短路+线段树.
线段树优化建图...
建两颗线段树,从一个线段树的节点出发,到另一颗线段树对应的节点即可。
同时把叶节点对应连起来.
然后每次连边新建一个中间的节点,不然直接连也可以,不过那样边数是\(O(n\log^2 n)\)的.
Code
/************************************************************** Problem: 3073 User: BeiYu Language: C++ Result: Accepted Time:17520 ms Memory:226032 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; #define mid ((l+r)>>1) #define lc (o<<1) #define rc (o<<1|1) #define uor(i,j,k) for(int i=j;i<=(int)k;i++) #define uep(i,j,k) for(int i=j;i<(int)k;i++) const int N = 5005000; inline int in(int x=0,char s=getchar()) { while(s>'9'||s<'0')s=getchar(); while(s>='0'&&s<='9')x=x*10+s-'0',s=getchar();return x; } int n,m,s,cp,B; int id[N],d[N],b[N]; struct Edge { int v,w; }; bool operator < (const Edge &a,const Edge &b) { return a.w>b.w; } vector<Edge> g[N]; priority_queue<Edge> q; void AddEdge(int u,int v,int w) { g[u].push_back((Edge) { v,w }); } void Build1(int o,int l,int r) { // cout<<o<<" "<<l<<" "<<r<<endl; if(l==r) { cp=max(cp,o);return; } Build1(lc,l,mid),Build1(rc,mid+1,r); AddEdge(lc,o,0),AddEdge(rc,o,0); } void Build2(int o,int l,int r) { if(l==r) { id[l]=o;return; } Build2(lc,l,mid),Build2(rc,mid+1,r); AddEdge(o+B,lc+B,0),AddEdge(o+B,rc+B,0); } void get_id(int o,int l,int r,int L,int R,vector<int> &res) { if(L<=l && r<=R) { res.push_back(o);return; } if(L<=mid) get_id(lc,l,mid,L,R,res); if(R>mid) get_id(rc,mid+1,r,L,R,res); } void Dijstra(int s) { memset(d,0x3f,sizeof(d)); d[s]=0,q.push((Edge) { s,0 }); for(int x;!q.empty();) { x=q.top().v,q.pop(); if(b[x]) continue;b[x]=1; uep(i,0,g[x].size()) { int v=g[x][i].v,w=g[x][i].w; if(d[x]+w<d[v]) { d[v]=d[x]+w; if(!b[v]) q.push((Edge) { v,d[v] }); } } } } void out() { uor(i,1,cp) { cout<<i<<"-->"; uep(j,0,g[i].size()) cout<<g[i][j].v<<"("<<g[i][j].w<<")"<<" "; cout<<endl; } } int main() { n=in(),m=in(),s=in(),Build1(1,1,n),B=cp,cp<<=1,Build2(1,1,n); uor(i,1,n) AddEdge(id[i]+B,id[i],0); uor(i,1,m) { int a=in(),b=in(),c=in(),d=in(),x; vector<int> aa,bb; aa.clear(),bb.clear(); get_id(1,1,n,a,b,aa),get_id(1,1,n,c,d,bb); x=++cp; uep(u,0,aa.size()) AddEdge(x,aa[u]+B,1); uep(v,0,bb.size()) AddEdge(bb[v],x,1); x=++cp; uep(v,0,bb.size()) AddEdge(x,bb[v]+B,1); uep(u,0,aa.size()) AddEdge(aa[u],x,1); } // cout<<B<<" "<<cp<<endl; // out(); vector<int> tmp;tmp.clear(),get_id(1,1,n,s,s,tmp),s=tmp[0]; // cout<<s<<endl; // uor(i,1,n) cout<<id[i]<<endl; Dijstra(s); for(int i=1;i<=n;i++) printf("%d\n",d[id[i]]>>1); return 0; }