POJ-1984-Navigation Nightmare

378 篇文章 0 订阅

题目是说给你n个线,并告知其方向,然后对于后面有一些询问,每个询问有一个时间点,要求你输出在该时间点a,b的笛卡尔距离,如果不存在则输出-1

对于所给的每条线进行相应的坐标转换,并且次进行并查集合并操作的时候要对所有坐标进行重新设定,注意算相对距离

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
const int maxn=40100;
struct node
{
    int x;
    int y;
}a[maxn];
struct Edge 
{
    int u;
    int v;
    int l;
    char dir[5];
}e[maxn];
int n,m,p[maxn];
int find(int x)
{
    if(p[x]==-1)
	return x;
    int y=p[x];
    p[x]=find(p[x]);
    a[x].x+=a[y].x;
    a[x].y+=a[y].y;
    return p[x];
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	memset(p,-1,sizeof(p));
	memset(a,0,sizeof(a));
	for(int i=0;i<m;i++)
	    scanf("%d%d%d%s",&e[i].u,&e[i].v,&e[i].l,&e[i].dir);
	int q,now=0;
	scanf("%d",&q);
	while(q--)
	{
	    int sa,sb,t;
	    scanf("%d%d%d",&sa,&sb,&t);
	    while(now<t)
	    {
		int u=e[now].u;
		int v=e[now].v;
		int x=find(e[now].u);
		int y=find(e[now].v);
		if(x==y)
		    continue;
		int x1=a[v].x;
		int y1=a[v].y;
		if(e[now].dir[0]=='E')
		{
		    a[y].x=a[u].x+e[now].l-a[v].x;
		    a[y].y=a[u].y-a[v].y;
		}
		else if(e[now].dir[0]=='W')
		{
		    a[y].x=a[u].x-e[now].l-a[v].x;
		    a[y].y=a[u].y-a[v].y;
		}
		else if(e[now].dir[0]=='S')
		{
		    a[y].x=a[u].x-a[v].x;
		    a[y].y=a[u].y-e[now].l-a[v].y;
		}
		else
		{
		    a[y].x=a[u].x-a[v].x;
		    a[y].y=a[u].y+e[now].l-a[v].y;
		}
		if(x!=y)
		    p[y]=x;
		now++;
	    }
	    int x=find(sa);
	    int y=find(sb);
	    if(x==y)
		printf("%d\n",abs(a[sa].x-a[sb].x)+abs(a[sa].y-a[sb].y));
	    else
		printf("-1\n");
	}
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值