标题效果:一些养殖场是由一些南北或东西向的道路互连。

镶上在不断的过程中会问两个农场是什么曼哈顿的距离,假设现在是不是通信。那么输出-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 并与正确集中检查的更多相关文章

  1. POJ 1984 Navigation Nightmare 【经典带权并查集】

    任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K To ...

  2. POJ 1984 Navigation Nightmare 带全并查集

    Navigation Nightmare   Description Farmer John's pastoral neighborhood has N farms (2 <= N <= ...

  3. POJ 1984 Navigation Nightmare (数据结构-并检查集合)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4072   Accepted: 1 ...

  4. POJ 1984 - Navigation Nightmare - [带权并查集]

    题目链接:http://poj.org/problem?id=1984 Time Limit: 2000MS Memory Limit: 30000K Case Time Limit: 1000MS ...

  5. POJ 1984 Navigation Nightmare(二维带权并查集)

    题目链接:http://poj.org/problem?id=1984 题目大意:有n个点,在平面上位于坐标点上,给出m关系F1  F2  L  D ,表示点F1往D方向走L距离到点F2,然后给出一系 ...

  6. poj 1984 Navigation Nightmare(带权并查集+小小的技巧)

    题目链接:http://poj.org/problem?id=1984 题意:题目是说给你n个线,并告知其方向,然后对于后面有一些询问,每个询问有一个时间点,要求你输出在该时间点a,b的笛卡尔距离,如 ...

  7. BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    Description 给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) . Sol 加权并查集. 像向量合成一样合并就可以了,找 \( ...

  8. POJ 1984 Navigation Nightmare

    并查集,给n个点和m条边,每条边有方向和长度,再给q个询问,第i个询问查询两个点之间在Ti时刻时的曼哈顿距离(能连通则输出曼哈顿距离,否则输出-1) 这题跟Corporative Network 有点 ...

  9. POJ - 1984 Navigation Nightmare 种类并查集

    思路:记录每个点与其根结点的横向距离和纵向距离,当知道其父节点与根结点的关系,很容易推出当前节点与根结点的关系: 直接相加即可. int p = a[x].par; a[x].dx += a[p].d ...

随机推荐

  1. python学习笔记之二:使用字符串

    这里会介绍如何使用字符串格式化其他的值,并了解一下利用字符串的分割,连接,搜索等方法能做些什么. 1.基本字符串操作 所有标准的序列操作(索引,分片,乘法,判断成员资格,求长度,取最大值和最小值)对字 ...

  2. Effective C++规定45 附加代码

    这部分是额外的代码的博客.键45条款想法已经实现. #include<iostream> using namespace std; template<typename T> c ...

  3. 将ACCESS数据库迁移到SQLSERVER数据库

    原文:将ACCESS数据库迁移到SQLSERVER数据库 将ACCESS数据库迁移到SQLSERVER数据库 ACCESS2000文件 用ACCESS2007打开,并迁移到SQLSERVER2005里 ...

  4. javascript实现的一个信息提示的小功能/

    //什么状况.CSDN的排版怎么这么多状况,还是本人太次?调整几次都没弄好.最后一遍了-- 最近由于公司业务问题.须要做一些面向公众的平台,于是对UI要求会高一点, 对于传统的alert的这样的方式来 ...

  5. crm采用soap删除记录

    //抽样 function demo() {     //操作记录id     var targetId = "A8A46444-BA10-E411-8A04-00155D002F02&qu ...

  6. ZOJ 2680 Clock()数学

    主题链接:problemId=1680" target="_blank">http://acm.zju.edu.cn/onlinejudge/showProblem ...

  7. IOS设计模式学习(21)享元

    1 前言 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pa ...

  8. JDK源码学习系列04----ArrayList

                                                                             JDK源码学习系列04----ArrayList 1. ...

  9. 数据结构 - trie

    #include <cstring> #include <iostream> #include <map> #include <cstdio> usin ...

  10. CentOS7卸载KDE桌面(转)

    最初安装centos时选择了安装KDE桌面,打开很卡,没有用到,想卸载,可是试了网上的方法什么yum groupremove kde-desktop 都不奏效,于是只能自己找出KDE的包,然后yum卸 ...