1 solutions
-
0
C++ :
#pragma GCC optimize ("O2") #include<queue> #include<cstdio> #include<cstring> #include<iostream> #define MAXN 30000 #define MAXM 100050 #define INF 0x3f3f3f3f #define idx(i,j) (i-1)*M+j using namespace std; typedef pair<int,int>pii; struct Query{ int x1,y1,x2,y2,s,t,id; }q[MAXM]; struct Edge{ int to[MAXM],val[MAXM],nxt[MAXM],head[MAXN],ent; void Init(){ent=2;} void Adde(int u,int v,int w){ to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++; to[ent]=u; val[ent]=w; nxt[ent]=head[v]; head[v]=ent++; } int Next(int i,bool type){ return type?head[i]:nxt[i]; } }E; int N,M,Q; int dis[MAXN],ans[MAXM],dx[MAXN],dy[MAXN]; void Dijkstra(int S,int X1,int Y1,int X2,int Y2,int w){ static bool vis[MAXN]; static int u,v; static priority_queue<pii,vector<pii>,greater<pii> >H; for(int i=X1;i<=X2;i++) for(int j=Y1;j<=Y2;j++){ u=idx(i,j); w==INF?dis[u]=INF:dis[u]+=w; vis[u]=0; } dis[S]=0; H.push(make_pair(0,S)); while(!H.empty()){ u=H.top().second; H.pop(); if(vis[u]) continue; vis[u]=1; for(int i=E.Next(u,1);i;i=E.Next(i,0)){ v=E.to[i]; if(dx[v]<X1||dx[v]>X2||dy[v]<Y1||dy[v]>Y2) continue; if(dis[v]<=dis[u]+E.val[i]) continue; dis[v]=dis[u]+E.val[i]; H.push(make_pair(dis[v],v)); } } } void Partition(int X1,int Y1,int X2,int Y2,int ql,int qr){ static Query tmp[MAXM]; if(ql>qr||X1>X2||Y1>Y2) return; if(X2-X1+1<=Y2-Y1+1){ int mid=(Y1+Y2)/2,L=ql,R=qr,S; dis[idx(X1,mid)]=INF; for(int i=X1;i<=X2;i++){ S=idx(i,mid); Dijkstra(S,X1,Y1,X2,Y2,dis[S]); for(int k=ql;k<=qr;k++) ans[q[k].id]=min(ans[q[k].id],dis[q[k].s]+dis[q[k].t]); } for(int k=ql;k<=qr;k++){ if(q[k].y1<mid&&q[k].y2<mid) tmp[L++]=q[k]; if(q[k].y1>mid&&q[k].y2>mid) tmp[R--]=q[k]; } for(int i=ql;i<L;i++) q[i]=tmp[i]; for(int i=qr;i>R;i--) q[i]=tmp[i]; Partition(X1,Y1,X2,mid-1,ql,L-1); Partition(X1,mid+1,X2,Y2,R+1,qr); } else{ int mid=(X1+X2)/2,L=ql,R=qr,S; dis[idx(mid,Y1)]=INF; for(int j=Y1;j<=Y2;j++){ S=idx(mid,j); Dijkstra(S,X1,Y1,X2,Y2,dis[S]); for(int k=ql;k<=qr;k++) ans[q[k].id]=min(ans[q[k].id],dis[q[k].s]+dis[q[k].t]); } for(int k=ql;k<=qr;k++){ if(q[k].x1<mid&&q[k].x2<mid) tmp[L++]=q[k]; if(q[k].x1>mid&&q[k].x2>mid) tmp[R--]=q[k]; } for(int i=ql;i<L;i++) q[i]=tmp[i]; for(int i=qr;i>R;i--) q[i]=tmp[i]; Partition(X1,Y1,mid-1,Y2,ql,L-1); Partition(mid+1,Y1,X2,Y2,R+1,qr); } } int main() { E.Init(); scanf("%d%d",&N,&M); for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) dx[idx(i,j)]=i,dy[idx(i,j)]=j; for(int i=1,w;i<=N;i++) for(int j=1;j<M;j++) scanf("%d",&w),E.Adde(idx(i,j),idx(i,j+1),w); for(int i=1,w;i<N;i++) for(int j=1;j<=M;j++) scanf("%d",&w),E.Adde(idx(i,j),idx(i+1,j),w); scanf("%d",&Q); for(int i=1;i<=Q;i++){ scanf("%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2); q[i].s=idx(q[i].x1,q[i].y1); q[i].t=idx(q[i].x2,q[i].y2); q[i].id=i; ans[i]=INF; } Partition(1,1,N,M,1,Q); for(int i=1;i<=Q;i++) printf("%d\n",ans[i]); return 0; }
- 1
Information
- ID
- 18812
- Time
- 8000ms
- Memory
- 256MiB
- Difficulty
- (None)
- Tags
- # Submissions
- 0
- Accepted
- 0
- Uploaded By