【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. MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理

    问题描述: 第一次访问的时候很慢,后面再次打开页面很快,过了一段时间不访问页面然后再次打开页面又像第一次那样很慢. 采用的技术和环境: 使用技术:EF6+MVC5 服务器环境:Windows 2012 ...

  2. 在Windows下编译WebRTC

    前言 这篇文章的目的在于为你节省生命中宝贵的10小时(甚至更多),或者浪费你10分钟.作为Google更新频繁的大型跨平台基础库,WebRTC的编译一直被人称为噩梦.如果恰巧你偏要在Windows下编 ...

  3. linux vsftpd 服务配置

    vsftpd.conf配置如下: # Example config file /etc/vsftpd/vsftpd.conf # # The default compiled in settings ...

  4. 左右选择框 js插件

    随着项目的进展,测试工程师在更多的浏览器中兼容性测试中,发现有些浏览器不支持option的触发事件,这就造成了先前一篇博文bootstrap 左右框多项选择示例 中左右选择框的失效,于是我就由原先的s ...

  5. ACM学习历程—HDU 5534 Partial Tree(动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534 题目大意是给了n个结点,让后让构成一个树,假设每个节点的度为r1, r2, ...rn,求f(x ...

  6. POJ1456:Supermarket

    浅谈堆:https://www.cnblogs.com/AKMer/p/10284629.html 题目传送门:http://poj.org/problem?id=1456 把物品按照时间排序,显然\ ...

  7. bzoj 1941 [Sdoi2010]Hide and Seek——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1941 第二道KDtree! 枚举每个点,求出距离它的最远和最近距离.O( n * logn ...

  8. bzoj 1043 下落的圆盘 —— 求圆心角、圆周长

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1043 求出每个圆没被覆盖的长度即可: 特判包含和相离的情况,注意判包含时 i 包含 j 和 ...

  9. Python 写文件时的Unicode设置

    今天在把Evenote的笔记内容写为文件时出错:     f.write(content) UnicodeEncodeError: &apos;gbk&apos; codec can& ...

  10. C++输入输出知识

    1.strtok将字符串中的单词用' '分割出来 #include<iostream> #include<cstdio> #include<cstdlib> #in ...