【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;
}

转载于:https://www.cnblogs.com/wangxiaodai/p/9765196.html

带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦相关推荐

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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3362 题目大意: 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤400 ...

  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 导航噩梦(加权并查集)

    3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 121  ...

  4. 2017乌鲁木齐区域赛I(带权并查集)

    #include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...

  5. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

  6. POJ1703带权并查集(距离或者异或)

    题意:       有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...

  7. POJ1988(带权并查集,搬砖块)

    题意:        可以这样理解,有n快方形积木,一开始都是单独的放到哪,然后有两种操作 1 M a b 把a所在的那一堆落到b所在那一堆的上面(一开始自己是一堆) 2 C a 问a下面有多少个积木 ...

  8. LA3027简单带权并查集

    题意:       有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...

  9. hdu3234 带权并查集(XOR)

    题意:       给你n个未知的正整数,有三总操作       I P V            P的值是V       I P Q V          P XOR Q = V       Q K ...

最新文章

  1. 正则式高人谈解答正则式的心得
  2. SpringMVC 框架系列之初识与入门实例
  3. 洛谷P3183食物链题解
  4. linux内核之内存管理.doc,linux内核之内存管理.doc
  5. WCF 第五章 行为 以属性为服务操作行为暴露一个参数检测器
  6. 做生意,没亏过钱,自然也没赚过钱
  7. Scrum联盟的新任全球营销副总裁访谈
  8. chengg0769 近期文章列表 垂直搜索相关(2007-07-10)
  9. Transact-SQL语言
  10. 秩和检验-matlab函数ranksum用法详解
  11. 备考分享!第十一届CDA考试Level Ⅱ 优秀考生采访
  12. 【Web:Bootstrap框架】简单实现理解
  13. 插值算法(最邻近差值、双线性插值、双三次插值)
  14. Cisco QoS配置说明(CBWFQ/LLQ/PQ/CQ/WFQ)
  15. 立方人物|吴胜男律师:一位温而不沸的90后执行主任
  16. 【前端笔记】SCSS学习篇之一:基础入门
  17. C++全套视频教程分享——
  18. RF自动化-RIDE(跑自动化注意事项)和(配置环境注意事项)
  19. 移动AI智能超算便携工作站
  20. HTML学习笔记 解决div浮动 高度塌陷问题

热门文章

  1. 微信开放平台(消息加解密接入指引)
  2. 重构系列之重构的标志:《重构》代码的坏味道
  3. jsp/java mysql图书馆管理系统毕业设计网站成品论文
  4. win7 64下RegOpenKeyEx返回的值不正确(转)
  5. 分形——故事之外丨陈关荣
  6. linux挂载sda4,Linux挂载磁盘
  7. DvaJS快速上手(3)
  8. System Repair Engineer (SREng) 2.5.16.900 版本
  9. 修改新建Word文档的默认字体、样式等
  10. 无法将值vmware-tray.exe写入注册表