BZOJ 3362 Navigation Nightmare 带权并查集

题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离

此题土豪题,不过POJ也有一道同样的题,可以刷一下

别被题目坑到了,这题不强制在线,把询问离线处理即可

然后就是带权并查集的问题了。。。将权值设为方向向量,重载+和-,按照正常权值并查集做就行了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 40400
using namespace std;
struct abcd{
	int x,y;
	abcd(){}
	abcd(int X,int Y):x(X),y(Y){}
	abcd operator + (const abcd &Y) const
	{
		return abcd( x+Y.x , y+Y.y );
	}
	abcd operator - (const abcd &Y) const
	{
		return abcd( x-Y.x , y-Y.y );
	}
}f[M];
struct operation{
	int x,y;
	abcd temp;
}operations[M];
struct query{
	int x,y,z,pos;
	bool operator < (const query &Y) const
	{
		return z < Y.z ;
	}
}queries[10100];
int n,m,q,fa[M],ans[10100];
int Distance(abcd x)
{
	return abs(x.x)+abs(x.y);
}
int Find(int x)
{
	if(!fa[x]||fa[x]==x)
		return fa[x]=x;
	int y=fa[x];
	fa[x]=Find(fa[x]);
	f[x]=f[y]+f[x];
	return fa[x];
}
int main()
{
	int i,j,x,y,z;
	char p[10];
	cin>>n>>m;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%d%s",&operations[i].x,&operations[i].y,&z,p);
		switch(p[0])
		{
			case 'E':operations[i].temp=abcd(z,0);break;
			case 'W':operations[i].temp=abcd(-z,0);break;
			case 'N':operations[i].temp=abcd(0,z);break;
			case 'S':operations[i].temp=abcd(0,-z);break;
		}
	}
	cin>>q;
	for(i=1;i<=q;i++)
		scanf("%d%d%d",&queries[i].x,&queries[i].y,&queries[i].z),queries[i].pos=i;
	sort(queries+1,queries+q+1);
	for(i=1,j=1;i<=q;i++)
	{
		for(;j<=queries[i].z;j++)
		{
			int x=operations[j].x;
			int y=operations[j].y;
			int fx=Find(x),fy=Find(y);
			fa[fy]=fx;
			f[fy]=f[x]-f[y]+operations[j].temp;
		}
		int x=queries[i].x;
		int y=queries[i].y;
		if( Find(x)!=Find(y) )
			ans[queries[i].pos]=-1;
		else
			ans[queries[i].pos]=Distance(f[x]-f[y]);
	}
	for(i=1;i<=q;i++)
		printf("%d\n",ans[i]);
}
时间: 2024-12-29 04:00:26

BZOJ 3362 Navigation Nightmare 带权并查集的相关文章

BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集

题目大意:一些农场由一些东西向或者南北向的路相互连接.在不断加边的过程中会询问两个农场的曼哈顿距离是多少,如果目前还不连通,那么输出-1. 思路:带权并查集,f[i]为点i到father[i]的距离,要维护两个值,一个是东西向的距离,一个是南北向的距离,因为以后更新的时候要用到.在合并的时候有些特殊.现在有一条边(x->y),设fx为x的根,fy为y的根,那么现在知道f到fx的距离,y到fy的距离,还知道x到y的距离,设fx到fy的距离为dis,则dis + f[y] = f[x] + edge

POJ 1984 - Navigation Nightmare - [带权并查集]

题目链接:http://poj.org/problem?id=1984 Time Limit: 2000MS Memory Limit: 30000K Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series of M (1 <= M < 40,000)

Navigation Nightmare——带权并查集(多权值)

题目链接 题意: 给出n个农场,然后按时间依次给出m个关于农场相对位置的信息,之后会给出询问,问在t时刻,x到y的曼哈顿距离是多少. 题解: dx[i]维护 根节点到 i 的横坐标距离   dy[i]维护 根节点到 i 的纵坐标距离 并查集高效的地方就在于在使用Find(x)函数查找x的父结点的时候会把沿途递归访问到的所有结点直接连到父节点上,使得下一次查询可以直接找到父节点,代码表示就是f[x]=Find(f[x]); 之前接触到的都是比较裸的并查集,但就像这题,维护并查集的时候还需要维护点到

POJ 1984 Navigation Nightmare 二维带权并查集

题目来源:POJ 1984 Navigation Nightmare 题意:给你一颗树 k次询问 求2点之间的曼哈顿距离 并且要在只有开始k条边的情况下 思路:按照方向 我是以左上角为根 左上角为原点 dx[i]为i点距离根的x坐标 dy[]是y坐标 这两个可以通过路径压缩求出 只不过是二维而已 #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int m

【POJ 1984】Navigation Nightmare(带权并查集)

Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series of M (1 <= M < 40,000) vertical and horizontal roads each of varying lengths (1 <= length <= 100

POJ 1984 Navigation Nightmare 【经典带权并查集】

任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7783   Accepted: 2801 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usuall

【BZOJ 3376】[Usaco2004 Open]Cube Stacking 方块游戏 带权并查集

这道题一开始以为是平衡树结果发现复杂度过不去,然后发现我们一直合并而且只是记录到最低的距离,那么就是带权并查集了,带权并查集的权一般是到根的距离,因为不算根要好打,不过还有一些其他的,具体的具体打. #include <cstdio> #include <cstring> const int N=30050; int h[N],f[N],size[N]; char s[2]; inline int find(int x){ if(f[x]==x)return x; int temp

【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)

题意:一个账本记录了N个月以来的收入情况,现在有一个侦探员不同时间偷看到M段时间内的总收入,问这个账本是否为假账. 解法:带权并查集+前缀和.   判断账本真假是通过之前可算到的答案与当前读入的值是否相同来完成.那么就是只有知道新读入的区间2端的(在相同区域内的!!)前缀和才可以判断,也就是这2个端点之前被纳入了相同的区域内才可以判断.于是,我们就可以想到并查集了.(( ′? ??`) 真的么......)   假设已知x~y月的总收入为d,那么s[y]-s[x-1]=d.一般前缀和是算上自己的

poj1984 带权并查集(向量处理)

Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2102 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series o