您的位置:首页 > Web前端

[BZOJ3362][Usaco2004 Feb]Navigation Nightmare 导航噩梦(加权并查集)

2016-12-15 17:30 363 查看

题目描述

传送门

题解

注意:时间乱序

加权并查集,维护两个参,互不影响。

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 400005

int n,m,Q,t,x,y,now,ans
;
struct hq{int x,y,w;char d;}e
;
struct hp{int a,b;}dis
;
struct ho{int x,y,t,id;}q
;
int f
;

int cmp(ho a,ho b)
{
return a.t<b.t;
}
int find(int x)
{
if (f[x]!=x)
{
int t=find(f[x]);
dis[x].a+=dis[f[x]].a;
dis[x].b+=dis[f[x]].b;
f[x]=t;
}
return f[x];
}
int Abs(int x)
{
return (x>0)?x:-x;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) f[i]=i;
for (int i=1;i<=m;++i) scanf("%d%d%d %c",&e[i].x,&e[i].y,&e[i].w,&e[i].d);
scanf("%d",&Q);
for (int i=1;i<=Q;++i) scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].t),q[i].id=i;
sort(q+1,q+Q+1,cmp);
now=1;
for (int i=1;i<=Q;++i)
{
x=q[i].x,y=q[i].y,t=q[i].t;
while (now<=t)
{
int f1=find(e[now].x),f2=find(e[now].y);
int a=0,b=0;
switch(e[now].d)
{
case 'N':a=e[now].w;break;
case 'S':a=-e[now].w;break;
case 'W':b=e[now].w;break;
case 'E':b=-e[now].w;break;
}
if (f1!=f2)
{
dis[f1].a=dis[e[now].y].a-dis[e[now].x].a+a;
dis[f1].b=dis[e[now].y].b-dis[e[now].x].b+b;
f[f1]=f2;
}
now++;
}
if (find(x)!=find(y)) ans[q[i].id]=-1;
else ans[q[i].id]=Abs(dis[y].a-dis[x].a)+Abs(dis[y].b-dis[x].b);
}
for (int i=1;i<=Q;++i) printf("%d\n",ans[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: