题意:依据n个Famr之间有限的连接关系,求解指定两个Farm之间的Manhattan distance
分析:
1.k个Query依据时间点的顺序输入
2.对于输入的每一个连接关系,动态更新合并树的相对坐标。
//Date: 2015.04.21
//Time: 125ms
//Memory: 1564k
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX=40005;
int sum[MAX];
int n,m,k;
struct Farm{
int x,y,tree,next;
}farms[MAX];
struct Information{
int f1,f2,dx,dy;
}data[MAX];
void Update(int t1,int t2,int dx,int dy){
int i=t2,p;
while(~i){
farms[i].tree=t1;
farms[i].x += dx;
farms[i].y += dy;
p=i;i=farms[i].next;
}
farms[p].next=farms[t1].next;
farms[t1].next=t2;
sum[t1]=sum[t1]+sum[t2]+1;
}
void init(){
memset(data,0,sizeof(data));
memset(sum,0,sizeof(sum));
memset(farms,0,sizeof(farms));
for(int i=1;i<=n;i++){
farms[i].tree=i;
farms[i].next=-1;
}
}
int main(){
int i,j,t,len,f1,f2,t1,t2;
char dir;
scanf("%d%d",&n,&m);
init();
for(i=0;i<m;i++){
scanf("%d %d %d %c",&data[i].f1,&data[i].f2,&len,&dir);
switch(dir){
case 'E':data[i].dx= len;break;
case 'S':data[i].dy=-len;break;
case 'W':data[i].dx=-len;break;
case 'N':data[i].dy= len;break;
}
}
scanf("%d",&k);
for(j=i=0;i<k;i++){
scanf("%d %d %d",&f1,&f2,&t);
for(;j<t;j++){
t1=farms[data[j].f1].tree;t2=farms[data[j].f2].tree;
if(sum[t1]>=sum[t2])
Update(t1,t2,farms[data[j].f1].x+data[j].dx-farms[data[j].f2].x,farms[data[j].f1].y+data[j].dy-farms[data[j].f2].y);
else
Update(t2,t1,farms[data[j].f2].x-data[j].dx-farms[data[j].f1].x,farms[data[j].f2].y-data[j].dy-farms[data[j].f1].y);
}
t1=farms[f1].tree;t2=farms[f2].tree;
if(t1!=t2)
printf("-1\n");
else
printf("%d\n",abs(farms[f1].x-farms[f2].x)+abs(farms[f1].y-farms[f2].y));
}
return 0;
}