题意:依据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; }