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;
}