poj1984:带权并查集

poj1984

题解:

让你求两个点之间的哈密顿距离。

可以分别维护横坐标和纵坐标的前缀和。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int const N = 40000 + 10;
int n,m,k,q;
int l[N],r[N],d[N],dir[N],sumx[N],sumy[N],fa[N];
int ql[N],qr[N],time[N];
int ans[N];
int dire[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
int find(int x){
	if(x != fa[x]){
		int t = fa[x];
		fa[x] = find(fa[x]);
		sumx[x] += sumx[t];
		sumy[x] += sumy[t];
	}
	return fa[x];
}
void Init(){
	cin>>n>>m;
	for(int i=0;i<=n;i++)
		sumx[i] = sumy[i] = 0,fa[i] = i;
	for(int i=1;i<=m;i++){
		char c;
		cin>>l[i]>>r[i]>>d[i]>>c;
		if(c == 'N')	dir[i] = 0;
		else if(c == 'S')	dir[i] = 1;
		else if(c == 'W')	dir[i] = 2;
		else if(c == 'E')	dir[i] = 3;
	}
	cin>>q;
	for(int i=1;i<=q;i++)
		cin>>ql[i]>>qr[i]>>time[i];
}
int main(){
	ios::sync_with_stdio(false);
	Init();
	for(int i=1;i<=m;i++){
		int x = l[i],	y = r[i];
		int fx = find(x),	fy = find(y);
		if(fx != fy){
			fa[fy] = fx;
			sumx[fy] = sumx[x] + dire[dir[i]][0] * d[i] - sumx[y];
			sumy[fy] = sumy[x] + dire[dir[i]][1] * d[i] - sumy[y];
		}
		for(int j=1;j<=q;j++){
			if(time[j] != i)	continue;
			x = ql[j], y = qr[j];
			fx = find(x),	fy = find(y);
			if(fx != fy)	ans[j] = -1;
			else	ans[j] = abs(sumx[x]-sumx[y]) + abs(sumy[x]-sumy[y]);
		}
	}
	for(int i=1;i<=q;i++)	cout<<ans[i]<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值