题意:给定一组线段和方向,然后查询点的距离。
思路:并查集的基本操作,在记录坐标偏移的时候注意一下,两个点之间和他们的根之间的坐标偏移关系可以用关系式表达出来,只要在纸上写一写就ok。查询输入的时候还是按ind排下序在处理线段。
/*
* 简单题 并查集的使用,就当是复习了。
*/
#include < iostream >
#include < cstdio >
#include < algorithm >
#include < memory.h >
#include < cmath >
#include < bitset >
#include < queue >
#include < vector >
using namespace std;
const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 40005 ;
const int INF = 1000000000 ;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
typedef struct {
int x,y;
}Node;
typedef struct {
int a,b;
int x,y;
}Road;
typedef struct {
int a,b;
int ind;
}Ask;
bool cmp( const Ask & a, const Ask & b)
{
return a.ind < b.ind;
}
Node node[MAXN];
Road road[MAXN * 1000 ];
Ask qus[MAXN * 10 ];
int n,m,k;
int pre[MAXN];
int init()
{
for ( int i = 0 ; i < MAXN; ++ i)
node[i].x = node[i].y = 0 ;
CLR(pre, - 1 );
return 0 ;
}
int find_set( int x)
{
int root = x;
int c_px,c_py,p_py,p_px;
int tmp = 0 ;
p_px = node[x].x;
p_py = node[x].y;
while (pre[root] >= 0 )
{
root = pre[root];
node[x].x += node[root].x;
node[x].y += node[root].y;
}
while ( x != root)
{
tmp = pre[x];
c_px = p_px;
c_py = p_py;
p_px = node[tmp].x;
p_py = node[tmp].y;
node[tmp].x = node[x].x - c_px;
node[tmp].y = node[x].y - c_py;
pre[x] = root;
x = tmp;
}
return root;
}
void union_set( const int & root1, const int & root2,
const int & x, const int & y)
{
pre[root2] += pre[root1];
pre[root1] = root2;
node[root1].x = x;
node[root1].y = y;
return ;
}
void print()
{
for ( int i = 1 ; i <= n; ++ i)
printf( " (%d,%d) " ,node[i].x,node[i].y);
printf( " %\n " );
}
int input()
{
int root1,root2,x,y,i,j,a,b,len;
char c;
for (i = 0 ; i < m; ++ i)
{
scanf( " %d %d %d %c " , & road[i].a, & road[i].b, & len, & c);
x = y = 0 ;
if (c == ' N ' )
y = len;
else if (c == ' S ' )
y = - len;
else if (c == ' W ' )
x = - len;
else
x = len;
road[i].x = x;
road[i].y = y;
}
IN(k);
for (i = 0 ; i < k; ++ i)
scanf( " %d%d%d " , & qus[i].a, & qus[i].b, & qus[i].ind);
return 0 ;
}
int work()
{
int i,j,tmp,root1,root2,ans,a,b,t,x,y;
int pre = 0 ;
sort(qus,qus + k,cmp);
for (i = 0 ; i < k; ++ i)
{
a = qus[i].a;
b = qus[i].b;
t = qus[i].ind;
for (; pre < t; ++ pre)
{
root1 = find_set(road[pre].a);
root2 = find_set(road[pre].b);
if (root1 == root2)
continue ;
x = road[pre].x - node[road[pre].a].x + node[road[pre].b].x;
y = road[pre].y - node[road[pre].a].y + node[road[pre].b].y;
union_set(root1,root2,x,y);
}
root1 = find_set(a);
root2 = find_set(b);
ans = - 1 ;
if (root1 != root2)
OUT(ans);
else
{
root1 = ABS(node[a].x - node[b].x);
root2 = ABS(node[a].y - node[b].y);
ans = root1 + root2;
OUT(ans);
}
}
return 0 ;
}
int main()
{
while (scanf( " %d%d " , & n, & m) != EOF)
{
init();
input();
work();
}
return 0 ;
}