BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
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 导航噩梦的更多相关文章
- 带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
[bzoj]3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂 ...
- BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集 Description 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M( ...
- BZOJ3362 [Usaco2004 Feb]Navigation Nightmare 导航噩梦
标题效果:自脑补. 思维:与维护两个维度和可设置为检查右. 注意,标题给予一堆关系的.我们应该加入两对关系. Code: #include <cstdio> #include <cs ...
- BZOJ 3362 POJ 1984 Navigation Nightmare 并与正确集中检查
标题效果:一些养殖场是由一些南北或东西向的道路互连. 镶上在不断的过程中会问两个农场是什么曼哈顿的距离,假设现在是不是通信.那么输出-1. 思维:并与正确集中检查,f[i]点i至father[i]距离 ...
- 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²) -- ...
- 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计
Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...
- BZOJ 3365: [Usaco2004 Feb]Distance Statistics 路程统计
Description 一棵树,统计距离不大于 \(k\) 的点对个数. Sol 点分治. 发现自己快把点分治忘干净了... 找重心使所有儿子的最大值尽量小,然后每次处理全部子树,再减去每个子树的贡献 ...
- BZOJ 3364: [Usaco2004 Feb]Distance Queries 距离咨询
Description 一棵树,询问两点间距离. Sol 倍增. 方向没用. 没有然后了. Code /************************************************ ...
- BZOJ 3363: [Usaco2004 Feb]Cow Marathon 奶牛马拉松
Description 给你一个图,两个点至多有一条路径,求最长的一条路径. \(n \leqslant 4\times 10^4\) Sol DFS?DP? 这就是一棵树,方向什么的都没用... 然 ...
随机推荐
- Dynamic Font Programming
http://www.braynzarsoft.net/Articles/index.php?p=VA&article=Easy-Font-Rendering-in-DirectX-11 ht ...
- PCH 配置
$(SRCROOT)/$(PROJECT)/PrefixHeader.pch
- 设计模式学习——观察者模式(Observer Pattern)
0. 前言 观察者模式在许多地方都能够用到,特别是作为MVC模式的一部分,在MVC中,模型(M):存放数据,视图(V):显示数据.当模型中的数据发生改变时,视图会得到通知,这是典型的观察者模式. 1. ...
- JavaScript中变量和函数声明的提升
现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...
- JavaBean出现的目的
一.JavaBean出现的目的 由于只用JSP开发会发现使用了很多的Scriptlet,会使得jsp文件非常混乱.如果使用了JavaBean,则可以大大减少JSP中代码量. JSP的理想状态是只负责显 ...
- linux下svn的命令
原文地址:http://www.cnblogs.com/wanqieddy/archive/2011/06/09/2076783.html
- C语言Hello world
#include"stdio.h" void main() { printf("Hello world!\n"); }
- for while (list each)的用法
each是返回数组 指针当前指向的 元素的 索引和值: 索引有四个值: 0, 1, key, value. 0和key是一样的, 1和value是一样的 但是each只是将数组指针 向前移动 一步, ...
- EF-在EF中运行sql语句
DbRawSqlQuery<int> result2 = db.Database.SqlQuery<int>("SELECT count(*) FROM test.s ...
- QS2016年全球高等教育系统实力排名 中国排名世界第八亚洲第一
2016年5月18日,QS发布"2016年全球高等教育系统实力排名",中国在此榜单表现优异,排名世界第八亚洲第一. 排名指标 排名指标及计算方法如下: 系统实力:QS大学排名前70 ...