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 ...
随机推荐
- C# AES要解密的数据的长度无效
加密方式 AES-CBC-128 将解密方法改成如下 public string Decrypt(string toDecrypt, string key) { if (string.IsNullO ...
- Hash冲突的解决方法
虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的.当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时.冲突就难免会发 生.另外,当关键字的实际取值大于哈希表的长度时,而且表中 ...
- 03-Linux各目录及每个目录的详细介绍
Linux各目录及每个目录的详细介绍 [常见目录说明] 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所 ...
- Quatz入门
Demo SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); Scheduler sched = sched ...
- Maven 多项目依赖,需要验证artifact的output root中是否包含其他项目输出
- 查看python中已安装的包有哪些
新版本执行:pip list 老版本执行:pip freeze
- 【RF库测试】Encode String To Bytes&Decode Bytes To String& should be string&should be unicode string &should not be string
场景1:判断类型 r ${d} set variable \xba\xcb\xbc\xf5\xcd\xa8\xb9\xfd #核减通过 Run Keyword And Continue On Fail ...
- LinQ的初步学习与总结
嘿嘿,说起来ORM和LinQ,就感觉离我好遥远的,在学校是没有学习的,所以总感觉学习了LinQ就是大神,现在嘛,终于也体会一点,感觉LinQ只是初步学习,没有太难,当然以后使用在项目中就没有这样的简单 ...
- Android学习之位图BitMap
BitMap代表一张位图,扩展名可以是.bmp或者.dib.位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2.4.8.16.24和32位色彩.例如 ...
- 【Python系列】python关键字、符号、数据类型等分类
https://github.com/AndyFlower/Python/blob/master/sample/python前言如下部分为python关键字,操作符号,格式字符.转义字符等,以后有时间 ...