社区讨论

只能过样例:(

P3350[ZJOI2016] 旅行者参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@ltb0ox9q
此快照首次捕获于
2024/03/03 12:33
2 年前
此快照最后确认于
2024/03/03 15:03
2 年前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
#define se second
#define fr first
const int N = 2e5+1145,INF = 1e9;
typedef pair<int,int> PII;
int mp[N],n,m,q,ans[N];

inline int zf(int x,int y){return (x-1)*n+y; }
inline int dyx(int id){ return ((id-1)/n)+1; }
inline int dyy(int id){ return ((id-1)%n)+1; }
struct ASK{
	int x,y,xx,yy,id;
};
int first[N],idx;
struct edge{
	int ne,d,val;
}ed[N*2];
void add_edge(int e,int d,int val){
	idx++,ed[idx].d=d,ed[idx].val=val,ed[idx].ne=first[e],first[e]=idx;
}
int dist[N],vis[N];
void dijkstra(int s,int lx,int rx,int ly,int ry){
	priority_queue<PII,vector<PII>,greater<PII> > Q;
	for(int i=lx;i<=rx;i++) 
		for(int j=ly;j<=ry;j++) 
			dist[zf(i,j)]=INF,vis[zf(i,j)]=0;
	Q.push(make_pair(0,s));
	dist[s]=0;
	while(Q.size()){
		int t=Q.top().se;
		Q.pop();
		if(vis[t]) continue;
		vis[t]=1;
		for(int i=first[t];i;i=ed[i].ne){
			int d=ed[i].d;
			if(dist[d]>dist[t]+ed[i].val&&dyx(d)>=lx&&dyx(d)<=rx&&dyy(d)>=ly&&dyy(d)<=ry){
				dist[d]=dist[t]+ed[i].val;
				Q.push(make_pair(dist[d],d));
			}
		}
	}
}

void solve(int lx,int rx,int ly,int ry,vector<ASK> opt){
	
	if(!opt.size()) return ;
	if(lx==rx && ly==ry) {
		for(int i=0;i<opt.size();i++) ans[opt[i].id]=0;
		return ;
	} 
	if(rx-lx>=ry-ly){//横切 
		int mid=rx+lx>>1;
		for(int i=ly;i<=ry;i++){
			dijkstra(zf(mid,i),lx,rx,ly,ry);
			for(int j=0;j<opt.size();j++) {
				ans[opt[j].id]=min(ans[opt[j].id],dist[zf(opt[j].x,opt[j].y)]+dist[zf(opt[j].xx,opt[j].yy)]);
//				if(j==0) printf("%d %d %d %d QWQ %d %d %d\n ",lx,rx,ly,ry,i,dist[zf(opt[j].x,opt[j].y)],dist[zf(opt[j].xx,opt[j].yy)]);
			}
		}
		vector<ASK> L,R;
		for(int i=0;i<opt.size();i++) 
		    if(max(opt[i].x,opt[i].xx)<=mid) L.push_back(opt[i]);
			else if(min(opt[i].x,opt[i].xx)>mid) R.push_back(opt[i]);
		solve(lx,mid,ly,ry,L),solve(mid+1,rx,ly,ry,R);
	}else{//纵切 
		int mid=ry+ly>>1;
		for(int i=lx;i<=rx;i++){
			dijkstra(zf(i,mid),lx,rx,ly,ry);
			for(int j=0;j<opt.size();j++) ans[opt[j].id]=min(ans[opt[j].id],dist[zf(opt[j].x,opt[j].y)]+dist[zf(opt[j].xx,opt[j].yy)]);
		}
		vector<ASK> L,R;
		for(int i=0;i<opt.size();i++) 
		    if(max(opt[i].y,opt[i].yy)<=mid) L.push_back(opt[i]);
			else if(min(opt[i].y,opt[i].yy)>mid) R.push_back(opt[i]);
		solve(lx,rx,ly,mid,L),solve(lx,rx,mid+1,ry,R);
	}
}

int main()
{
	memset(ans,0x3f,sizeof ans);
	cin>>n>>m;
	for(int val,i=1;i<=n;i++) 
		for(int j=1;j<m;j++) 
			scanf("%d",&val),add_edge(zf(i,j),zf(i,j+1),val),add_edge(zf(i,j+1),zf(i,j),val);
	for(int val,i=1;i<n;i++) 
		for(int j=1;j<=m;j++) 
			scanf("%d",&val),add_edge(zf(i,j),zf(i+1,j),val),add_edge(zf(i+1,j),zf(i,j),val);
	vector<ASK> opt;
	cin>>q;
	for(int i=1;i<=q;i++) {
		int u,v,uu,vv;
		scanf("%d%d%d%d",&u,&v,&uu,&vv);
		opt.push_back({u,v,uu,vv,i});
	}
	solve(1,n,1,m,opt);
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...