首页 > 其他分享 >ZJOI2016 旅行者 题解

ZJOI2016 旅行者 题解

时间:2024-12-24 16:30:34浏览次数:3  
标签:int 题解 mid 旅行者 second vector ZJOI2016 first fo

ZJOI2016 旅行者 题解

题目大意:

给定一个 \(n\times m\) 的网格图,相邻的四连通的点之间有给定边权的双向边,有 \(Q\) 个离线询问,问两个点之间的最短路。

\(n\times m\le 2\times 10^4,Q\le 10^5\)。

发现了吗?和上次省选组的三角剖分那道题很像,这种平面图上的最短路很有可能是分治。

考虑每次把矩形割成两半,分治处理询问。

如果询问在分割线两侧,那么路径一定跨过分割线,一定形如 \((x,s)+(s,y)\),其中 \(s\) 为分割线上的点,于是枚举分割线上的点,对全图跑最短路。

如果询问在分割线同侧,对于路径不跨过的直接递归处理完了,但有可能路径仍跨过分割线,此时一定形如 \((x,s)+(s,y)\),是同理的。

注意我们需要每次割边长较长的一边才能保证复杂度正确。

考虑计算时间复杂度,我们实际可以把矩形看做 \(n\times n\) 的正方形,每次分治两层可以得到 \(4\) 个 \((n/2)\times (n/2)\) 的正方形。

\[T(n)=4T(n/2)+O(n^3\log (n^2))+O(Qn) \]

根据主定理 \(a=4,b=2,d>3\),因此 \(\log _b a<d\),所以时间复杂度为 \(O(n^3\log (n^2)+Qn)\)。

设 \(T=nm\le 2\times 10^4\),那么复杂度为 \(O(T\sqrt T\log T+QT)\)。

AC 代码,使用动态数组实现:

const int maxq=1e5+5;
const int inf=0x3f3f3f3f;
int ans[maxq];
struct qry{
	int x1,y1,x2,y2,num;
};
void solve(int n,int m,vector<vector<int>> &r,vector<vector<int>> &c,vector<qry> &q){
	if(!q.size())return;
	if(n<m){
		for(auto &i:q)swap(i.x1,i.y1),swap(i.x2,i.y2);
		vector<vector<int>> nr(m+1,vector<int>(n+1,0));
		vector<vector<int>> nc(m+1,vector<int>(n+1,0));
		fo(i,1,n)fo(j,1,m-1)nc[j][i]=r[i][j];
		fo(i,1,n-1)fo(j,1,m)nr[j][i]=c[i][j];
		r=nr,c=nc;
		swap(n,m);
	}
	if(n==1){
		for(auto i:q)ans[i.num]=0;
		return;
	}
	vector<qry> q1,q2;
	int mid=n/2;
	for(auto i:q){
		if(i.x1<=mid && i.x2<=mid) q1.push_back(i);
		else if(i.x1>mid && i.x2>mid) q2.push_back({i.x1-mid,i.y1,i.x2-mid,i.y2,i.num});
	}
	vector<vector<int>> r1(mid+1,vector<int>(m+1,0));
	vector<vector<int>> r2(n-mid+1,vector<int>(m+1,0));
	vector<vector<int>> c1(mid+1,vector<int>(m+1,0));
	vector<vector<int>> c2(n-mid+1,vector<int>(m+1,0));
	fo(i,1,mid)fo(j,1,m-1)r1[i][j]=r[i][j];
	fo(i,1,mid-1)fo(j,1,m)c1[i][j]=c[i][j];
	fo(i,mid+1,n)fo(j,1,m-1)r2[i-mid][j]=r[i][j];
	fo(i,mid+1,n-1)fo(j,1,m)c2[i-mid][j]=c[i][j];
	solve(mid,m,r1,c1,q1),solve(n-mid,m,r2,c2,q2);
	fo(i,1,m){
		vector<vector<int>> dis(n+1,vector<int>(m+1,inf));
		vector<vector<bool>> vis(n+1,vector<bool>(m+1,false));
		dis[mid][i]=0;
		priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<>> p;
		p.push({0,{mid,i}});
		while(p.size()){
			auto u=p.top().second; p.pop();
			if(vis[u.first][u.second]) continue;
			vis[u.first][u.second]=1;
			auto update=[&](int x,int y,int d)->void{
				if(dis[x][y]>d)dis[x][y]=d,p.push({d,{x,y}});	
			};
			if(u.first>1)update(u.first-1,u.second,c[u.first-1][u.second]+dis[u.first][u.second]);
			if(u.first<n)update(u.first+1,u.second,c[u.first][u.second]+dis[u.first][u.second]);
			if(u.second>1)update(u.first,u.second-1,r[u.first][u.second-1]+dis[u.first][u.second]);
			if(u.second<m)update(u.first,u.second+1,r[u.first][u.second]+dis[u.first][u.second]);
		}
		for(auto j:q){
			ans[j.num]=min(ans[j.num],dis[j.x1][j.y1]+dis[j.x2][j.y2]);
		}
	}
}
signed main(){
	int n,m,Q;
	read(n,m);
	vector<vector<int>> r(n+1,vector<int>(m+1,0));
	vector<vector<int>> c(n+1,vector<int>(m+1,0));
	fo(i,1,n)fo(j,1,m-1)read(r[i][j]);
	fo(i,1,n-1)fo(j,1,m)read(c[i][j]);
	read(Q);
	vector<qry> q(Q);
	fu(i,0,Q){
		read(q[i].x1,q[i].y1,q[i].x2,q[i].y2);
		q[i].num=i+1;
		ans[i+1]=inf;
	}
	solve(n,m,r,c,q);
	fo(i,1,Q)write(ans[i],'\n');
	return 0;
}

标签:int,题解,mid,旅行者,second,vector,ZJOI2016,first,fo
From: https://www.cnblogs.com/dccy/p/18628036

相关文章

  • 省选模拟题解
    \(T1\)题解题意:有一张\(n\)个点的有标号无向图,分为了\(k\)个连通块,第\(i\)个连通块的大小是\(s_i\),每个连通块都是完全图(节点之间两两有边)。要加\(k-1\)条边使得图连通,计算所有连边方案的权值和。假设第\(i\)个连通块被多加了\(d_i\)条边,那么该连边方案的权值为\(......
  • 湖南科技大学2024年计算机程序设计新生赛题解
    @目录前言前置知识补充问题A:珂朵莉解题思路代码问题B:可莉的烦恼解题思路代码问题C:小A的画解题思路代码问题D:KMP自动机fail树dfs序建可持久化线段树解题思路代码问题E:谜题:结局解题思路代码问题F:奶龙列阵(easyversion)解题思路代码问题G:小A的密码解题思路代码问......
  • [BZOJ2741][FOTILE模拟赛] L 题解
    相当好的题目,虽然和我前几天出的题重了qwq。\(lmx\)是我们的红太阳,没有他我们就会死!!!暴力枚举一个端点,然后用可持久化\(01\Trie\)或者离线\(Trie\)(当然这题用不了,但不强制在线的话是可以的)得到答案。时间复杂度\(O(nm\logn)\),过不了,考虑优化。红太阳\(lmx\)曾经说过:当......
  • umount: /xxx: target is busy问题解决
    在卸载文件系统的时候,提示umount:/tqls_system:targetisbusy,表示挂载的文件系统正在被使用。要卸载文件系统,必须结束使用文件或者目录的进程`fuser`命令用于查看使用特定文件或者文件系统的进程ID主要参数如下:```-mNAME,--mountNAME NAMEspecifiesafileonamou......
  • USACO24DEC Cake Game S 题解 [ 黄 ] [ 前缀和 ] [ adhoc ]
    CakeGame:小清新前缀和题,但是我场上想了半天优先队列贪心假完了/ll/ll/ll。观察本题有三个重要的结论,我们依次进行观察。不难发现,第二个牛一定会拿\(\frac{n}{2}-1\)个蛋糕走。同时它拿走的蛋糕一定是左边一段、右边一段。如果它要使自己的分数最大化,那么显然就是要将左边和......
  • CF2048D 题解
    提供一种非常naive且暴力的思路。小于等于Kevin的选手没有任何贡献,扣掉。我们发现,我们如果按轮次一个个填充这一堆比赛,实际上是可以确定一个(可能的)最优填充次序的。先填Kevin会做的。这些题目不影响排名。再按\(b_i\)从大到小依次填充。这样是最优的,因为\(b_i\)越小......
  • ZZJCACM个人训练赛23题解
    原题链接Ahttps://codeforces.com/contest/1999/problem/A800Bhttps://qoj.ac/contest/1794/problem/9310Chttps://codeforces.com/problemset/problem/2008/D1100Dhttps://qoj.ac/contest/1485/problem/8081Ehttps://codeforces.com/contest/2002/problem/B......
  • 第36次ccf-csp题解(思维)
    比赛链接https://sim.csp.thusaac.com/contest/36/home 比赛感受这会刚打完上海icpc,比起区域赛的题,这个简单太多了。感受还不错,写的很顺手。除了第3题,其他3题都是一发过。刷题得长期刷。      A题移动 题意:f:y+1; b:y-1; ......
  • 期望问题+ybt题解
    算法理解对于随机变量\(X\),有\(n\)个可能的取值,取值为\(x_i\)有\(P(x_i)\)的概率,则它的数学期望则为\(E(X)=\sum_{i=1}^nx_iP(x_i)\)性质其中期望的线性限制最重要,它可以将两个完全独立的期望拆分开来单独计算,详见例题T1:首先我们观察有\(n\)道题,我们根据期望的线......
  • 题解:CF2048F Kevin and Math Class
    Problemstatement给定长度为\(n\)的数组\(a,b\),每次操作可以任意选择一个区间\([l,r]\),记\(x=\displaystyle\min_{l\leqi\leqr}b_i\),然后\(\foralla_i(i\in[l,r]),a_i\leftarrow\lfloor{\frac{a_i}{x}}\rfloor\),求最终使得\(a_i\)均变为\(1\)的最小操作次......