【bzoj】3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

​ 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂直或水

平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样,

图中农场用F1..F7表示, 每个农场最多能在东西南北四个方向连结4个不同的农场.此外,农场只处在道路的两端.道路不会交叉且每对农场间有且仅有一条路径.邻居鲍伯要约翰来导航,但约翰丢了农场的地图,他只得从电脑的备份中修复了.每一条道路的信息如下:

从农场23往南经距离10到达农场17

从农场1往东经距离7到达农场17

​ 当约翰重新获得这些数据时,他有时被的鲍伯的问题打断:“农场1到农场23的曼哈顿距离是多少?”所谓在(XI,Yi)和(X2,y2)之间的“曼哈顿距离”,就是lxl - X21+lyl - y21.如果已经有足够的信息,约翰就会回答这样的问题(在上例中答案是17),否则他会诚恳地抱歉并回答-1.

Input

​ 第1行:两个分开的整数N和M.

​ 第2到M+1行:每行包括4个分开的内容,F1,F2,三,D分别描述两个农场的编号,道路的长度,F1到F2的方向N,E,S,w.

​ 第M+2行:一个整数,K(1≤K≤10000),表示问题个数.

​ 第M+3到M+K+2行:每行表示一个问题,由3部分组成:Fi,F2,,.其中Fi和F2表示两个被问及的农场.而/(1≤J≤M)表示问题提出的时刻.J为1时,表示得知信息1但未得知信息2时.

Output

​ 第1到K行:每行一个整数,回答问题.表示两个农场间的曼哈顿距离.不得而知则输出-1.

两点之间只有一条路径,所以这是一颗树。又因为要判断两点是否连通,可以想到用并查集维护。

又因为要维护两点之间的曼哈顿距离,所以用带权并查集维护每个点到其祖先的x距离和y距离。

带权并查集小白表示这道题让我很难受。

首先在路径压缩的时候,代码很容易写出来:

int find(int x){
if(f[x]==x)return x;
itn t=f[x];
f[x]=find(f[x]);
dx[x]+=dx[t];
dy[x]+=dy[t];
return f[x];
}

之后我们把操作排序离线。

那么对于合并的操作,我认为才是最大的难点。

首先给出代码:

while(now<=q[i].p){
int ta=find(q[i].x);int tb=find(q[i].y);
if(ta!=tb){
f[ta]=tb;
dx[ta]=dx[b[now]]+cx[now]-dx[a[now]];
dy[ta]=dy[b[now]]+cy[now]-dy[a[now]];
}
now++;
}

重点是对于dx和dy的更新。

那画个图其实就好理解了。

注意边是有方向的。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int wx=40017;
int f[wx],dx[wx],dy[wx],a[wx],b[wx],cx[wx],cy[wx],ans[wx];
int n,m,t;
char opt[5];
inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
return sum*f;
}
int find(int x){
if(x==f[x])return x;
int t=f[x];
f[x]=find(f[x]);
dx[x]+=dx[t];
dy[x]+=dy[t];
return f[x];
}
struct node{
int x,y,p,id;
friend bool operator < (const node& a,const node& b)
{
return a.p<b.p;
}
}q[wx];
int main(){
n=read();read();
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<n;i++){
a[i]=read();b[i]=read();t=read();scanf("%s",opt+1);
if(opt[1]=='E')cx[i]=t;
if(opt[1]=='W')cx[i]=-t;
if(opt[1]=='N')cy[i]=t;
if(opt[1]=='S')cy[i]-=t;
}
m=read();
for(int i=1;i<=m;i++){
q[i].x=read();q[i].y=read();q[i].p=read();q[i].id=i;
}
sort(q+1,q+1+m);
int now=1;
for(int i=1;i<=m;i++){
while(now<=q[i].p){
int ta=find(a[now]);
int tb=find(b[now]);
if(ta!=tb){
f[ta]=tb;
dx[ta]=dx[b[now]]+cx[now]-dx[a[now]];
dy[ta]=dy[b[now]]+cy[now]-dy[a[now]];
}
now++;
}
int ta=find(q[i].x),tb=find(q[i].y);
ans[q[i].id]=(ta==tb?abs(dx[q[i].x]-dx[q[i].y])+abs(dy[q[i].x]-dy[q[i].y]):-1);
// now++;
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
return 0;
}

带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦的更多相关文章

  1. BZOJ3362 [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    标题效果:自脑补. 思维:与维护两个维度和可设置为检查右. 注意,标题给予一堆关系的.我们应该加入两对关系. Code: #include <cstdio> #include <cs ...

  2. BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集

    BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description     农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...

  3. BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    Description 给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) . Sol 加权并查集. 像向量合成一样合并就可以了,找 \( ...

  4. bzoj3376/poj1988[Usaco2004 Open]Cube Stacking 方块游戏 — 带权并查集

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3376 题目大意: 编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方 ...

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

    这道题一开始以为是平衡树结果发现复杂度过不去,然后发现我们一直合并而且只是记录到最低的距离,那么就是带权并查集了,带权并查集的权一般是到根的距离,因为不算根要好打,不过还有一些其他的,具体的具体打. ...

  6. 初涉「带权并查集」&&bzoj3376: [Usaco2004 Open]Cube Stacking 方块游戏

    算是挺基础的东西 Description     约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.    游戏开始后,约翰会给贝茜发出P(1≤P ...

  7. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  8. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  9. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

随机推荐

  1. 10 Python 数据类型—集合

    在Python set是基本数据类型的一种集合类型,它有可变集合(set())和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法 ...

  2. Javascript-- jQuery DOM篇(一)

    DOM创建节点及节点属性 通过JavaScript可以很方便的获取DOM节点,从而进行一系列的DOM操作.但实际上一般开发者都习惯性的先定义好HTML结构,但这样就非常不灵活了. 浏览器提供的一些原生 ...

  3. 幻想乡三连B:连在一起的幻想乡

    $G[k][x]$表示所有$x$个点的无向图中每一个图的边数的$k$次方之和. $F[k][x]$就是在$G[k][x]$的基础上加了一个整体连通的性质. 有一个经典的套路就是对于$F$在对应的$G$ ...

  4. 对存在JavaScript隐式类型转换的四种情况的总结

    一般存在四种情况,JavaScript会对变量的数据类型进行转换. 目录 * if中的条件会被自动转为Boolean类型 * 会被转为false的数据 * 会被转为true的数据 * 参与+运算都会被 ...

  5. Operating System-Thread(2) Multi-Process-Parallel vs Multi-Thread-Parallel

    本文主要介绍线程的模型 一.Multi-Process-Parallel vs Multi-Thread-Parallel 多进程的并行:CPU在多个进程之间进行切换,系统给人一种多个进程在并行执行的 ...

  6. MySQL函数不能创建的解决方法(转)

    在使用MySQL数据库时,有时会遇到MySQL函数不能创建的情况.下面就教您一个解决MySQL函数不能创建问题的方法,供您借鉴参考. 出错信息大致类似: ERROR 1418 (HY000): Thi ...

  7. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  8. 使用ceph命令提示handle_connect_reply connect got BADAUTHORIZER

    输入命令提示如下错误: [root@node1 ~]# rados -p testpool ls 2017-10-21 06:13:25.743045 7f8f89b6d700 0 -- 192.16 ...

  9. Mac搭建nginx+rtmp服务器

    nginx是非常优秀的开源服务器,用它来做hls或者rtmp流媒体服务器是非常不错的选择,本人在网上整理了安装流程,分享给大家并且作备忘. 一.安装Homebrow 已经安装了brow的可以直接跳过这 ...

  10. C# 将html实体编码转换到正常字符 & #40;格式

    获取到html实体编码字符后,通过正则获取其中的html实体编码,再统一强制转换到正常字符: 代码如下: string strformat = item.value7; //将html实体编码转换到正 ...