Description

给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) .

Sol

加权并查集.

像向量合成一样合并就可以了,找 \(f[x]\) 的时候需要先记录现在的父节点,然后更新他新的父节点.

Code

/**************************************************************
Problem: 3362
User: BeiYu
Language: C++
Result: Accepted
Time:80 ms
Memory:3712 kb
****************************************************************/ #include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std; typedef pair< int,int > pr;
#define abs(x) ((x)<0 ? -(x) : (x) )
#define mpr make_pair
#define debug(a) cout<<#a<<"="<<a<<" "
const int N = 40005; int n,m,k;
int f[N],ans[N];pr g[N];
struct Q{ int a,b,c,d; }q[N],qq[N]; inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x ;}
inline char read(char ch=getchar()){ while(ch>'Z' || ch<'A') ch=getchar();return ch; }
pr operator + (const pr &a,const pr &b){ return mpr(a.first+b.first,a.second+b.second); }
pr operator += (pr &a,const pr &b){ return a=a+b; }
pr operator - (const pr &a,const pr &b){ return mpr(a.first-b.first,a.second-b.second); }
pr operator -= (pr &a,const pr &b){ return a=a-b; }
int cmp1(const Q &x,const Q &y){ return x.c<y.c; }
int cmp2(const Q &x,const Q &y){ return x.d<y.d; }
int find(int x){
if(f[x] == x) return x;
int t=f[x];f[x]=find(f[x]);
g[x]+=g[t];return f[x];
}
void work(int u,int v,int w,char d){
int r1=find(u),r2=find(v);
// debug(r1),debug(r2)<<endl;
// cout<<u<<" "<<v<<" "<<w<<" "<<d<<endl;
// cout<<"qwq"<<endl;
if(r1!=r2) switch(d){
case 'N':f[r1]=r2,g[r1]=g[v]+mpr(0,w)-g[u];break;
case 'W':f[r1]=r2,g[r1]=g[v]+mpr(-w,0)-g[u];break;
case 'S':f[r1]=r2,g[r1]=g[v]+mpr(0,-w)-g[u];break;
default:f[r1]=r2,g[r1]=g[v]+mpr(w,0)-g[u];break;
}
// for(int i=1;i<=n;i++) cout<<find(i)<<":("<<g[i].first<<","<<g[i].second<<") ";cout<<endl;
}
int main(){
// freopen("in.in","r",stdin);
n=in(),m=in();
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++) qq[i].a=in(),qq[i].b=in(),qq[i].c=in(),qq[i].d=read();
k=in();for(int i=1;i<=k;i++) q[i].a=in(),q[i].b=in(),q[i].c=in(),q[i].d=i;
sort(q+1,q+k+1,cmp1);
// for(int i=1;i<=m;i++) work(qq[i].a,qq[i].b,qq[i].c,qq[i].d);
// for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")\n"; for(int i=1,j=1,u,v,r1,r2;i<=k;i++){
for(;j<=q[i].c && j<=n;++j) work(qq[j].a,qq[j].b,qq[j].c,qq[j].d);
u=q[i].a,v=q[i].b,r1=find(u),r2=find(v);
if(r1==r2){
// debug(u),debug(v),debug(g[u].first),debug(g[v].first),debug(g[u].second),debug(g[v].second)<<endl;
ans[q[i].d]=abs(g[u].first-g[v].first)+abs(g[u].second-g[v].second);
}else ans[q[i].d]=-1;
}
// for(int i=1;i<=n;i++) cout<<find(i)<<" ("<<g[i].first<<","<<g[i].second<<")\n";
for(int i=1;i<=k;i++) printf("%d\n",ans[i]);
return 0;
}

  

BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦的更多相关文章

  1. 带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    [bzoj]3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 ​ 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂 ...

  2. BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集

    BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description     农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...

  3. BZOJ3362 [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    标题效果:自脑补. 思维:与维护两个维度和可设置为检查右. 注意,标题给予一堆关系的.我们应该加入两对关系. Code: #include <cstdio> #include <cs ...

  4. BZOJ 3362 POJ 1984 Navigation Nightmare 并与正确集中检查

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

  5. BZOJ 3367: [Usaco2004 Feb]The Big Game 球赛( dp )

    dp(i)表示前i个人最少坐多少辆车, dp(i) = min(dp(j) + 1, dp(i)) (0 <= j < i 且 (i, j]的人能坐在一辆车上) 时间复杂度O(n²) -- ...

  6. 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计

    Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...

  7. BZOJ 3365: [Usaco2004 Feb]Distance Statistics 路程统计

    Description 一棵树,统计距离不大于 \(k\) 的点对个数. Sol 点分治. 发现自己快把点分治忘干净了... 找重心使所有儿子的最大值尽量小,然后每次处理全部子树,再减去每个子树的贡献 ...

  8. BZOJ 3364: [Usaco2004 Feb]Distance Queries 距离咨询

    Description 一棵树,询问两点间距离. Sol 倍增. 方向没用. 没有然后了. Code /************************************************ ...

  9. BZOJ 3363: [Usaco2004 Feb]Cow Marathon 奶牛马拉松

    Description 给你一个图,两个点至多有一条路径,求最长的一条路径. \(n \leqslant 4\times 10^4\) Sol DFS?DP? 这就是一棵树,方向什么的都没用... 然 ...

随机推荐

  1. centos 查看是32位还是64位

    查看linux机器是32位还是64位的方法: file /sbin/init 或者 file /bin/ls/sbin/init: ELF 64-bit LSB executable, x86-64, ...

  2. 20145212 《Java程序设计》第10周学习总结

    20145212 <Java程序设计>第10周学习总结 学习内容总结 一.Java的网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net ...

  3. GLEW OpenGL Access violation when using glGenVertexArrays

    http://stackoverflow.com/questions/20766864/glew-opengl-access-violation-when-using-glgenvertexarray ...

  4. top命令详解(转,详细)

    来源:脚本之家(http://www.jb51.net/article/40807.htm) 本文通过一个运行中的WEB服务器的top监控截图,讲述top视图中的各种数据的含义,还包括视图中各进程(任 ...

  5. mysql 查询表结构 查询索引

    首先进入到mysql里 show databases; 选择数据库 use xxxcms; 查询数据库下的表结构 show create table 表名; 这样看着不太好可以后面加\G show c ...

  6. yii2 widget示例

    <?php namespace app\components; use yii\base\Widget; use yii\helpers\Html; class RctReplyWidget e ...

  7. jquery 中的事件冒泡

    废话少说,先来一段代码热热身: <!DOCTYPE html> <html> <head> <title>demo</title> < ...

  8. 浅谈JavaScript中的继承

    引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...

  9. Spring入门_03_构造注入

    实体类 Student.java package com.umgsai.spring.entity; import java.util.Date; public class Student { pri ...

  10. redis使用watch完成秒杀抢购功能(转)

    redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...