并查集,给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. PHP学习笔记:MySQL数据库的操纵

    Update语句 Update 表名 set 字段1=值1, 字段2=值2  where  条件 练习: 把用户名带  ‘小’的人的密码设置为123456@ 语句:UPDATE crm_user SE ...

  2. AngularJs Cookie 的使用

    最新在学习 AngularJs ,发现网上很难搜到 AngularJs.Cookie 教程, 就自己写篇博客,希望能帮到刚学的人. 废话不多说上代码 首先要引用 angular-cookies.js ...

  3. ASP.NET Core1.0 带来的新特性

    1.采用新的文件系统,不再通过工程文件(.sln和.csproj)来定义项目文件清单. 解决方案文件还是*.sln,但项目文件变成*.xproj了.在项目文件夹下新增的文件会被自动添加到项目中,不用再 ...

  4. PEM (Privacy Enhanced Mail) Encoding

    PEM (Privacy Enhanced Mail) Encoding The moPEM (Privacy Enhanced Mail) Encoding The most commonly us ...

  5. IOS6学习笔记(二)

    四.使用关联引用为分类添加数据 虽然不能在分类中创建实例变量,但是可以创建关联引用(associative reference).通过关联引用,你可以向任何对象中添加键-值(key-value)数据. ...

  6. swift学习笔记之-构造过程

    //构造过程 import UIKit /* 构造过程(Initialization): 1.构造过程是使用类.结构体或枚举类型的一个实例的准备过程.在新实例可用前必须执行这个过程,具体操作包括设置实 ...

  7. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q51-Q53)

    Question 51You use a third-party site definition to create SharePoint sites.You need to add a Web Pa ...

  8. Stooge排序与Bogo排序算法

    本文地址:http://www.cnblogs.com/archimedes/p/stooge-bogo-sort-algorithm.html,转载请注明源地址. Stooge排序算法 Stooge ...

  9. JAVA基础学习day16--集合三-Map、HashMap,TreeMap与常用API

    一.Map简述 1.1.简述 public interface Map<K,V> 类型参数: K - 此映射所维护的键的类型 key V - 映射值的类型 value 该集合提供键--值的 ...

  10. IOS中的多核并发编程GCD

    Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispat ...