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

这题跟Corporative Network 有点像,只不过那题是维护到根节点的距离,这题还要顺便维护与根节点的x,y方向的偏移量。findset时,每次找完father就要加上father的x、y坐标偏移量,这样findset完以后就得到了与根的偏移量。然后合并时, (注意,这里是 fa[x] = y)

dr[x].x = r.x - dr[r.u].x + dr[r.v].x;

dr[x].y = r.y - dr[r.u].y + dr[r.v].y;      即 x->y <==> u->v - u->x + v->y 如下图:

这题还要注意数据可能不是按照时间顺序输入的,要做一个排序,然后再按原来的顺序输出。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 40100 int fa[N],q; struct DR
{
int x,y;
}dr[N],to[]; struct ROAD
{
int u,v;
int x,y;
}road[N]; struct QUERY
{
int a,b,time;
int id,res;
}query[N]; void makeset(int n)
{
for(int i=;i<=n;i++)
{
fa[i] = i;
dr[i].x = dr[i].y = ;
}
} int findset(int x)
{
if(x != fa[x])
{
int tmp = fa[x];
fa[x] = findset(fa[x]);
dr[x].x += dr[tmp].x;
dr[x].y += dr[tmp].y;
}
return fa[x];
} void unionset(int index) //合并第index条边
{
ROAD r = road[index];
int x = findset(r.u);
int y = findset(r.v);
if(x == y)
return;
fa[x] = y;
dr[x].x = r.x - dr[r.u].x + dr[r.v].x; // x->y <==> u->v - u->x + v->y
dr[x].y = r.y - dr[r.u].y + dr[r.v].y;
} int cmp1(QUERY ka,QUERY kb)
{
return ka.time<kb.time;
} int cmp2(QUERY ka,QUERY kb)
{
return ka.id<kb.id;
} void InitDirection()
{
to['E'-'A'].x = ;
to['E'-'A'].y = ;
to['W'-'A'].x = -;
to['W'-'A'].y = ;
to['N'-'A'].x = ;
to['N'-'A'].y = ;
to['S'-'A'].x = ;
to['S'-'A'].y = -;
} void read()
{
int n,m,i,dis;
char ss[];
InitDirection();
scanf("%d%d",&n,&m);
makeset(n);
for(i=;i<=m;i++)
{
scanf("%d%d%d %s",&road[i].u,&road[i].v,&dis,ss);
road[i].x = dis*(to[ss[]-'A'].x);
road[i].y = dis*(to[ss[]-'A'].y);
}
scanf("%d",&q);
for(i=;i<=q;i++)
{
scanf("%d%d%d",&query[i].a,&query[i].b,&query[i].time);
query[i].id = i;
}
sort(query+,query+q+,cmp1);
} void solve()
{
int i,j;
j=;
for(i=;i<=q;i++)
{
for(;j<=query[i].time;j++)
{
unionset(j);
}
if(findset(query[i].a) != findset(query[i].b))
query[i].res = -;
else
query[i].res = abs(dr[query[i].a].x-dr[query[i].b].x) + abs(dr[query[i].a].y-dr[query[i].b].y);
}
sort(query+,query+q+,cmp2);
for(i=;i<=q;i++)
cout<<query[i].res<<endl;
} int main()
{
read();
solve();
return ;
}

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 POJ 1984 Navigation Nightmare 并与正确集中检查

    标题效果:一些养殖场是由一些南北或东西向的道路互连. 镶上在不断的过程中会问两个农场是什么曼哈顿的距离,假设现在是不是通信.那么输出-1. 思维:并与正确集中检查,f[i]点i至father[i]距离 ...

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

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

  9. POJ1984 Navigation Nightmare —— 种类并查集

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

随机推荐

  1. dbcp2和dbcp 1.4在API层面的差异

    近期处于某种原因,打算把所有系统的数据库连接统一升级到dbcp2.发现有几处与dbcp 1在API层面发生了变化,主要如下所示: dbcp 2:org.apache.commons.dbcp2.Bas ...

  2. winform(ListView及数据库连接)

    一.ListView:列表展示数据1.视图 - 在其右上方小箭头点击将视图改为Largelcon:或右键属性在外观View将其改为Details2.设置列头 - 在其右上方小箭头点击选择编辑列,然后添 ...

  3. QT5中全屏显示子窗口和取消全屏的方法

    问题描述:用QT5做了个MDI多窗体应用程序,想把子窗体全屏显示,用网上的方法,但总是遇到问题. 网上的解决方法原文在这:http://www.cnblogs.com/Rick-w/archive/2 ...

  4. javascript数组浅谈2

    上次说了数组元素的增删,的这次说说数组的一些操作方法 join()方法: ,,] arr.join("_") //1_2_3 join方法会返回一个由数组中每个值的字符串形式拼接而 ...

  5. 利用ng-click、ng-switch和click-class制作切换的tabl

    效果如下图,当分别点击1,2,3时,下面的不同颜色的div会切换 <html ng-app> <head> <title></title> <sc ...

  6. RecyclerView添加头部和底部视图的实现

    ListView是有addHeaderView和 addFooterView两个方法的. 但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法. 那么如果使用Recy ...

  7. Android logcat

    logcat是Android中一个命令行工具,可以用于得到程序的log信息. 基本命令 logcat使用方法如下所示: [adb] logcat [<option>] ... [<f ...

  8. 蓝牙Ibeacon室内定位和微信摇一摇周边原理分析

    苹果推出Ibeacon室内定位技术是为了弥补GPS无法覆盖室内定位这种场景.苹果意味着创新,在其推动下,蓝牙Ibeacon得到了极大的应用.而腾讯则是利用蓝牙Ibeacon在场景体验方面进行了创新,实 ...

  9. 基于Retrofit+RxJava的Android分层网络请求框架

    目前已经有不少Android客户端在使用Retrofit+RxJava实现网络请求了,相比于xUtils,Volley等网络访问框架,其具有网络访问效率高(基于OkHttp).内存占用少.代码量小以及 ...

  10. 如何获取QQ里的截图app?

    电脑系统平台:OS X EI Capitan 10.11 在以前的旧的QQ版本,QQ的截图的偏好还有一个开机自启动的选项: 现在新的版本,却没有了"开机自动运行"的选项,然而有时候 ...