poj 1984 并查集

时间:2025-01-17 23:38:14

题目意思是一个图中,只有上下左右四个方向的边。给出这样的一些边,

求任意指定的2个节点之间的距离。

就是看不懂,怎么破

 /*
POJ 1984
并查集
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std; const int MAXN=;
int F[MAXN];
int dx[MAXN],dy[MAXN]; int F1[MAXN],F2[MAXN],L[MAXN];
char D[MAXN][]; struct Node
{
int u,v;
int index;
int I;
}node[MAXN];
int ans[MAXN]; int find(int x)
{
if(F[x]==-)return x;
int tmp=find(F[x]);
dx[x]+=dx[F[x]];
dy[x]+=dy[F[x]];
return F[x]=tmp;
}
bool cmp(Node a,Node b)
{
return a.I<b.I;
}
int main()
{
int n,m;
int Q;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
while(scanf("%d%d",&n,&m)==)
{
memset(F,-,sizeof(F));
memset(dx,,sizeof(dx));
memset(dy,,sizeof(dy));
for(int i=;i<=m;i++)
{
scanf("%d%d%d%s",&F1[i],&F2[i],&L[i],&D[i]);
}
scanf("%d",&Q);
for(int i=;i<Q;i++)
{
scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].I);
node[i].index=i;
}
sort(node,node+Q,cmp);
int t=;
for(int i=;i<Q;i++)
{
while(t<=m&&node[i].I>=t)
{
int t1=find(F1[t]),t2=find(F2[t]);
if(t1!=t2)
{
F[t2]=t1;
if(D[t][]=='N')
{
dy[t2]=dy[F1[t]]-dy[F2[t]]+L[t];
dx[t2]=dx[F1[t]]-dx[F2[t]];
}
else if(D[t][]=='S')
{
dy[t2]=dy[F1[t]]-dy[F2[t]]-L[t];
dx[t2]=dx[F1[t]]-dx[F2[t]];
}
else if(D[t][]=='E')
{
dx[t2]=dx[F1[t]]-dx[F2[t]]+L[t];
dy[t2]=dy[F1[t]]-dy[F2[t]];
}
else if(D[t][]=='W')
{
dx[t2]=dx[F1[t]]-dx[F2[t]]-L[t];
dy[t2]=dy[F1[t]]-dy[F2[t]];
}
}
t++;
}
if(find(node[i].u)!=find(node[i].v))ans[node[i].index]=-;
else
{
ans[node[i].index]=abs(dx[node[i].u]-dx[node[i].v])+abs(dy[node[i].u]-dy[node[i].v]);
}
}
for(int i=;i<Q;i++)printf("%d\n",ans[i]);
}
return ;
}