您的位置:首页 > Web前端

POJ 1984/BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦

2016-11-02 09:56 501 查看
愚蠢的我才刚会打带权并查集呢。。

每个点要用两个权值记录 x y 即他与父亲节点的相对距离

然后并查集的时候 加起来就好了

接着自定义一下咯 什么东是x+1之类的

每次知道两个点 x 到 y的距离 把fa[fx]=fy fx到fy的距离就是 fx->x->y->fy

(其实自己用向量yy一下就好,fx->x就用x->fx反过来就好)

注意 题目是 U V E/W/N/S 是指U在V 的...侧 别看错了

对了 这题的读入略恶心啊。 温馨提示POJ的询问是有序的 BZOJ上的是无序的

放个两个都能过的代码吧。(重载运算符还是挺爽的)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int N=40008,inf=1e9;
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct node{
int x,y;
node(){}
node(int a,int b){x=a;y=b;}
node operator +(const node &a){return node(a.x+x,a.y+y);}
node operator -(const node &a){return node(a.x-x,a.y-y);}
}p
;
int dis(node x){return abs(x.x)+abs(x.y);}
struct o{int x,y; node u;}a
;
struct g{int x,y,t,id;}l[N>>2];
int Cmp(g x1,g x2){return x1.t<x2.t;}
int f
,n,m,q,ans[N>>2];
int fa(int x)
{
if(x==f[x])return x;
int y=f[x];
f[x]=fa(f[x]),p[x]=p[x]+p[y];
return f[x];
}
int main()
{
int i,j,x,y,c,qx,qy; char ch;
n=read(),m=read();
for(i=1;i<=n;i++)f[i]=i;
for(i=1;i<=m;i++)
{
a[i].x=read(),a[i].y=read(),c=read();
scanf("\n%c",&ch);
if(ch=='E')a[i].u.x=c;
if(ch=='W')a[i].u.x=-c;
if(ch=='N')a[i].u.y=c;
if(ch=='S')a[i].u.y=-c;
}
q=read();
for(i=1;i<=q;i++)
l[i].x=read(),l[i].y=read(),l[i].t=read(),l[i].id=i;
sort(l+1,l+1+q,Cmp);
for(i=j=1;i<=q;i++)
{
for(;j<=l[i].t;j++)
{
x=fa(a[j].x),y=fa(a[j].y);
f[x]=y; p[x]=p[a[j].y]-p[a[j].x]-a[j].u;
}
x=fa(l[i].x),y=fa(l[i].y);
if(x!=y)ans[l[i].id]=-1;
else ans[l[i].id]=dis(p[l[i].x]-p[l[i].y]);
}
for(i=1;i<=q;i++)printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: