POJ 1984 Navigation Nightmare (并查集)

题意:给定一组线段和方向,然后查询点的距离。

思路:并查集的基本操作,在记录坐标偏移的时候注意一下,两个点之间和他们的根之间的坐标偏移关系可以用关系式表达出来,只要在纸上写一写就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 ;
}

 

你可能感兴趣的:(poj)