POJ 1984 - Navigation Nightmare - [带权并查集]
题目链接:http://poj.org/problem?id=1984
Time Limit: 2000MS Memory Limit: 30000K Case Time Limit: 1000MS
Description
F1 --- (13) ---- F6 --- (9) ----- F3
| |
(3) |
| (7)
F4 --- (20) -------- F2 |
| |
(2) F5
|
F7
Being an ASCII diagram, it is not precisely to scale, of course.
Each farm can connect directly to at most four other farms via roads that lead exactly north, south, east, and/or west. Moreover, farms are only located at the endpoints of roads, and some farm can be found at every endpoint of every road. No two roads cross, and precisely one path
(sequence of roads) links every pair of farms.
FJ lost his paper copy of the farm map and he wants to reconstruct it from backup information on his computer. This data contains lines like the following, one for every road:
There is a road of length 10 running north from Farm #23 to Farm #17
There is a road of length 7 running east from Farm #1 to Farm #17
...
As FJ is retrieving this data, he is occasionally interrupted by questions such as the following that he receives from his navigationally-challenged neighbor, farmer Bob:
What is the Manhattan distance between farms #1 and #23?
FJ answers Bob, when he can (sometimes he doesn't yet have enough data yet). In the example above, the answer would be 17, since Bob wants to know the "Manhattan" distance between the pair of farms.
The Manhattan distance between two points (x1,y1) and (x2,y2) is just |x1-x2| + |y1-y2| (which is the distance a taxicab in a large city must travel over city streets in a perfect grid to connect two x,y points).
When Bob asks about a particular pair of farms, FJ might not yet have enough information to deduce the distance between them; in this case, FJ apologizes profusely and replies with "-1".
Input
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Each line contains four space-separated entities, F1,
F2, L, and D that describe a road. F1 and F2 are numbers of
two farms connected by a road, L is its length, and D is a
character that is either 'N', 'E', 'S', or 'W' giving the
direction of the road from F1 to F2.
* Line M+2: A single integer, K (1 <= K <= 10,000), the number of FB's
queries
* Lines M+3..M+K+2: Each line corresponds to a query from Farmer Bob
and contains three space-separated integers: F1, F2, and I. F1
and F2 are numbers of the two farms in the query and I is the
index (1 <= I <= M) in the data after which Bob asks the
query. Data index 1 is on line 2 of the input data, and so on.
Output
* Lines 1..K: One integer per line, the response to each of Bob's
queries. Each line should contain either a distance
measurement or -1, if it is impossible to determine the
appropriate distance.
Sample Input
7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6 1
1 4 3
2 6 6
Sample Output
13
-1
10
Hint
At time 3, the distance between 1 and 4 is still unknown.
At the end, location 6 is 3 units west and 7 north of 2, so the distance is 10.
题意:
有n个节点,给出m条数据,每条数据包含F1,F2,L,D,代表从节点F1到F2的距离为L,D为'E/W/S/N',代表了F1→F2是指向东/西/南/北;
现在又有个人来给出k条询问,每条询问包含F1,F2,IDX,代表了查询节点F1和F2之间的距离,本次查询发生在录入第IDX条数据之后(也就是说本次查询时,第IDX+1条往后的数据都还是未知的);
注意:对于查询的回答,必须按照查询输入的顺序进行输出;同时可能在读入第idx条数据之后,读入第idx+1条数据之前,会有多个查询。
题解:
并查集建树,par[x]代表x的父亲节点,val[x].X和val[x].Y分别代表par[x]->x向量的水平分量和竖直分量;
注意做好find()函数内val[x]的更新、unite两个节点时val[]更新,并且注意将答案按照查询的顺序输出即可。
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=+; int n,m,k; int par[maxn];
struct Val{
int X,Y; //par[x]->x向量的水平分量和竖直分量
}val[maxn];
void init(int l,int r){for(int i=l;i<=r;i++) par[i]=i,val[i].X=val[i].Y=;}
int find(int x)
{
if(par[x]==x) return x;
else
{
int root=find(par[x]);
val[x].X+=val[par[x]].X;
val[x].Y+=val[par[x]].Y;
return par[x]=root;
}
} struct Data{
int F1,F2,L;
char D[];
}data[maxn]; vector<int> D2Q[maxn]; //Data->Query
struct Query{
int F1,F2;
int id; //记录下是第id个查询
}query[maxn]; struct Res{
int val; //第id个查询的答案值
int id; //代表本结果是对应到第id个查询的
Res(int val,int id){this->val=val,this->id=id;}
bool operator<(const Res &oth)const
{
return id<oth.id;
}
}; int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++) scanf("%d%d%d%s",&data[i].F1,&data[i].F2,&data[i].L,data[i].D); scanf("%d",&k);
for(int i=;i<=n;i++) D2Q[i].clear();
for(int i=,idx;i<=k;i++)
{
scanf("%d%d%d",&query[i].F1,&query[i].F2,&idx);
query[i].id=i;
D2Q[idx].push_back(query[i].id); //记录一下第i个询问发生在第idx个数据之后
} init(,n);
vector<Res> res;
for(int i=,a,b,t1,t2;i<=m;i++)
{
a=data[i].F1, b=data[i].F2;
t1=find(a), t2=find(b);
if(t1!=t2)
{
par[t2]=t1;
int dX,dY; //dX是a->b向量的水平分量,dY是a->b向量的竖直分量
if(data[i].D[]=='E') dX=data[i].L, dY=;
if(data[i].D[]=='W') dX=-data[i].L, dY=;
if(data[i].D[]=='N') dX=, dY=data[i].L;
if(data[i].D[]=='S') dX=, dY=-data[i].L;
val[t2].X=val[a].X+dX-val[b].X;
val[t2].Y=val[a].Y+dY-val[b].Y;
} //在录入本次数据之后,查看是否有查询,若有尝试进行回答
for(int j=,_size=D2Q[i].size();j<_size;j++)
{
Query Q=query[D2Q[i][j]];
a=Q.F1, b=Q.F2;
t1=find(a), t2=find(b); int ans;
if(t1!=t2) ans=-;
else ans=abs(val[a].X-val[b].X)+abs(val[a].Y-val[b].Y); res.push_back(Res(ans,Q.id)); //将查询结果进行记录
}
} sort(res.begin(),res.end()); //将查询的结果按照之前查询的顺序排列
for(int i=;i<res.size();i++) printf("%d\n",res[i].val);
}
POJ 1984 - Navigation Nightmare - [带权并查集]的更多相关文章
- POJ 1984 Navigation Nightmare 带全并查集
Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= ...
- BZOJ 3362 Navigation Nightmare 带权并查集
题目大意:给定一些点之间的位置关系,求两个点之间的曼哈顿距离 此题土豪题.只是POJ也有一道相同的题,能够刷一下 别被题目坑到了,这题不强制在线.把询问离线处理就可以 然后就是带权并查集的问题了.. ...
- POJ-1984-Navigation Nightmare+带权并查集(中级
传送门:Navigation Nightmare 参考:1:https://www.cnblogs.com/huangfeihome/archive/2012/09/07/2675123.html 参 ...
- POJ 1773 Parity game 带权并查集
分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2: ...
- POJ 1182 食物链 【带权并查集】
<题目链接> 题目大意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我 ...
- POJ 1182 食物链 (带权并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 78551 Accepted: 23406 Description ...
- POJ 1182 食物链 【带权并查集/补集法】
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说 ...
- POJ 1733 Parity game (带权并查集)
题意:有序列A[1..N],其元素值为0或1.有M条信息,每条信息表示区间[L,R]中1的个数为偶数或奇数个,但是可能有错误的信息.求最多满足前多少条信息. 分析:区间统计的带权并查集,只是本题中路径 ...
- poj 1182 食物链【带权并查集】
设相等的边权为0,吃的边权为,被吃的边权为2,然后用带权并查集在%3的意义下做加法即可 关系为简单环的基本都可以用模环长的方式是用带权并查集 #include<iostream> #inc ...
随机推荐
- 关于Android打版本号的小白文
尽管常常和android打交道.但事实上我对android不是非常了解. 这里记录一下ant编译androidproject的过程,然后顺便记录一下android的一些基本概念.不求渡人,但求渡己.这 ...
- POJ1159——Palindrome
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 53647 Accepted: 18522 Desc ...
- CentOS 6.3 + Subversion + Usvn 搭建版本管理服务器
一. Subversion 简介 Subversion是一个自由,开源的版本控制系统.在Subversion管理下,文件和目录可以超越时空.Subversion将文件存放在中心版本库里.这个版本库很像 ...
- 编译Android 必须安装的库
要安装的库: 正在卸载 build-essential ...正在卸载 g++-multilib ...正在卸载 g++ ...正在卸载 gcc-multilib ...正在卸载 gcc ...正在卸 ...
- es 5.0的下载安装for mac
为了学习es的同学少走些弯路,特此记下笔记,以供学习. 我装的es是5.4.3 一,下载安装es, 1,es 5.0之后变化很大,对jdk要求为1.8,(先升级jdk) 2,下载地址 :https:/ ...
- codeforces水题100道 第十题 Codeforces Round #277 (Div. 2) A. Calculating Function (math)
题目链接:www.codeforces.com/problemset/problem/486/A题意:求表达式f(n)的值.(f(n)的表述见题目)C++代码: #include <iostre ...
- RabbitMQ笔记四:Binding,Queue,Message概念
Binding详解 黄线部分就是binding Exchange与Exchange,Queue之间的虚拟连接,Binding中可以包含Routing key或者参数 创建binding 注意: ...
- 【前端积累】javascript事件
什么是事件? 事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信.就是文档或浏览器窗口发生的一些特定的交互瞬间(某种动作). 1.事件流 事件流描述的是从页面中接收事件的顺序. 1)事件 ...
- 【前端系列】移动前端开发之viewport的深入理解
在页面上没有设置width所以样式显示有问题,本来选择的响应式模式的320*410结果看到页面的实际宽度确实980px. 本文转载自: 在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的 ...
- 【VI】如何再执行上一个(历史)命令(已解决)
输入命令提示符( : )+ 上下箭头(<Up/Down>键) 输入 :his 或者 :history 查看历史