BZOJ 3362 POJ 1984 Navigation Nightmare 并与正确集中检查
标题效果:一些养殖场是由一些南北或东西向的道路互连。
镶上在不断的过程中会问两个农场是什么曼哈顿的距离,假设现在是不是通信。那么输出-1。
思维:并与正确集中检查,f[i]点i至father[i]距离,为了维持两个值,一个是东西向的距离。一个是南北向的距离,由于以后更新的时候要用到。在合并的时候有些特殊。如今有一条边(x->y),设fx为x的根。fy为y的根,那么如今知道f到fx的距离。y到fy的距离。还知道x到y的距离,设fx到fy的距离为dis,则dis + f[y] = f[x] + edge[p].w,那么dis = f[x] - f[y] + edge[p].w。
依据这个公式来合并两个树就能够了。
CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 40010
using namespace std; struct Complex{
int x,y,len;
char c;
}edge[MAX];
struct Ask{
int x,y;
int pos,_id;
bool operator <(const Ask &a)const {
return pos < a.pos;
}
}ask[MAX];
struct Status{
int x,y; Status(int _,int __):x(_),y(__) {}
Status() {}
Status operator +(const Status &a)const {
return Status(x + a.x,y + a.y);
}
Status operator -(const Status &a)const {
return Status(x - a.x,y - a.y);
}
}f[MAX]; int points,edges,asks;
int father[MAX];
int ans[MAX]; char s[10]; void Pretreatment(); int Find(int x); int main()
{
cin >> points >> edges;
Pretreatment();
for(int i = 1;i <= edges; ++i) {
scanf("%d%d%d%s",&edge[i].x,&edge[i].y,&edge[i].len,s);
edge[i].c = s[0];
}
cin >> asks;
for(int i = 1;i <= asks; ++i)
scanf("%d%d%d",&ask[i].x,&ask[i].y,&ask[i].pos),ask[i]._id = i;
sort(ask + 1,ask + asks + 1);
int now = 1;
for(int i = 1;i <= edges; ++i) {
int fx = Find(edge[i].x);
int fy = Find(edge[i].y);
if(fx != fy) {
father[fy] = fx;
Status temp;
if(edge[i].c == 'N') temp = Status(0,edge[i].len);
if(edge[i].c == 'S') temp = Status(0,-edge[i].len);
if(edge[i].c == 'E') temp = Status(edge[i].len,0);
if(edge[i].c == 'W') temp = Status(-edge[i].len,0);
f[fy] = f[edge[i].x] - f[edge[i].y] + temp;
}
while(i >= ask[now].pos && now <= asks) {
int fx = Find(ask[now].x);
int fy = Find(ask[now].y);
if(fx != fy) ans[ask[now]._id] = -1;
else {
Status temp = f[ask[now].x] - f[ask[now].y];
ans[ask[now]._id] = abs(temp.x) + abs(temp.y);
}
++now;
}
}
for(int i = 1;i <= asks; ++i)
printf("%d\n",ans[i]);
return 0;
} void Pretreatment()
{
for(int i = 1;i <= points; ++i)
father[i] = i;
} int Find(int x)
{
if(father[x] == x) return x;
int temp = father[x];
father[x] = Find(father[x]);
f[x] = f[x] + f[temp];
return father[x];
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
BZOJ 3362 POJ 1984 Navigation Nightmare 并与正确集中检查的更多相关文章
- POJ 1984 Navigation Nightmare 【经典带权并查集】
任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K To ...
- POJ 1984 Navigation Nightmare 带全并查集
Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= ...
- POJ 1984 Navigation Nightmare (数据结构-并检查集合)
Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 4072 Accepted: 1 ...
- POJ 1984 - Navigation Nightmare - [带权并查集]
题目链接:http://poj.org/problem?id=1984 Time Limit: 2000MS Memory Limit: 30000K Case Time Limit: 1000MS ...
- POJ 1984 Navigation Nightmare(二维带权并查集)
题目链接:http://poj.org/problem?id=1984 题目大意:有n个点,在平面上位于坐标点上,给出m关系F1 F2 L D ,表示点F1往D方向走L距离到点F2,然后给出一系 ...
- poj 1984 Navigation Nightmare(带权并查集+小小的技巧)
题目链接:http://poj.org/problem?id=1984 题意:题目是说给你n个线,并告知其方向,然后对于后面有一些询问,每个询问有一个时间点,要求你输出在该时间点a,b的笛卡尔距离,如 ...
- BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
Description 给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) . Sol 加权并查集. 像向量合成一样合并就可以了,找 \( ...
- POJ 1984 Navigation Nightmare
并查集,给n个点和m条边,每条边有方向和长度,再给q个询问,第i个询问查询两个点之间在Ti时刻时的曼哈顿距离(能连通则输出曼哈顿距离,否则输出-1) 这题跟Corporative Network 有点 ...
- POJ - 1984 Navigation Nightmare 种类并查集
思路:记录每个点与其根结点的横向距离和纵向距离,当知道其父节点与根结点的关系,很容易推出当前节点与根结点的关系: 直接相加即可. int p = a[x].par; a[x].dx += a[p].d ...
随机推荐
- 八月份 CUGBACM_Summer_Tranning 题解
CUGBACM_Summer_Tranning4 比赛链接:http://vjudge.net/contest/view.action?cid=52230#overview 题解链接: F . HDU ...
- Mysql学习笔记(一)数据类型
原文:Mysql学习笔记(一)数据类型 学习内容: Mysql基本数据类型. 1.数字类型.. i.整型 Mysql数据类型 含义(有符号) tinyint(m ...
- hdu 1395 2^x mod n = 1 暴力过~~最好学下欧拉定理~~~
2^x mod n = 1 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- c# Use Properties Instead of Accessible Data Members
advantage of properties: 1 properties can be used in data binding, public data member can not. 2 dat ...
- ADO.NET连接方式
使用Command.DataReader和DataSet两种方法实现数据绑定 方法1:使用Command和DataReader SqlConnection con = new SqlConnectio ...
- 【原创】leetCodeOj --- Copy List with Random Pointer 解题报告
题目地址: https://oj.leetcode.com/problems/copy-list-with-random-pointer/ 题目内容: A linked list is given s ...
- JS 查找遍历子节点元素
function nextChildNode(node,clazz,tagName){ var count= node.childElementCount; for(var i=0;i<coun ...
- Android毛玻璃处理代码(Blur)
以下为将bitmap图像处理为毛玻璃效果的图像的工具类: public class FastBlurUtil { public static Bitmap doBlur(Bitmap sentBitm ...
- [LeetCode82]Remove Duplicates from Sorted List II
题目: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct ...
- Interpolator(插值器)的种类
Interpolator(插值器)的种类 Interpolator被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeat ...