题目链接:https://vjudge.net/problem/POJ-1984
解题思路:并查集+离线操作。
用dx[ ]和dy[ ]两个数组存储某点相对于该点所在集合的源头的方位,因此不难推知dx[ ]和dy[ ]要初始化为0。当把一个点依附到另一个点之上时所用的技巧值得细细体会。而finds( )函数则更是点睛之笔。
AC代码:
1 #include2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 const int maxn=40000+10; 8 int fa[maxn],dx[maxn],dy[maxn]; 9 struct input{ 10 int F1,F2,L; 11 char D[3]; 12 }inode[maxn]; 13 struct query{ 14 int F1,F2,I,ind; 15 }qnode[10005]; 16 bool cmp(const query &a,const query &b){ 17 return a.I<b.I; 18 } 19 int finds(int temp){ 20 if(fa[temp]==-1) 21 return temp; 22 int tp=finds(fa[temp]); 23 dx[temp]+=dx[fa[temp]]; 24 dy[temp]+=dy[fa[temp]]; 25 return fa[temp]=tp; 26 } 27 int ans[10005]; 28 int main(){ 29 memset(fa,-1,sizeof(fa)); 30 memset(dx,0,sizeof(dx)); 31 memset(dy,0,sizeof(dy)); 32 int N,M,K; 33 scanf("%d%d",&N,&M); 34 for(int i=0;i ) 35 scanf("%d%d%d%s",&inode[i].F1,&inode[i].F2,&inode[i].L,inode[i].D); 36 scanf("%d",&K); 37 for(int i=0;i ){ 38 scanf("%d%d%d",&qnode[i].F1,&qnode[i].F2,&qnode[i].I); 39 qnode[i].ind=i; 40 } 41 sort(qnode,qnode+K,cmp); 42 43 int j=0; 44 for(int i=0;i ){ 45 int t1=finds(inode[i].F1),t2=finds(inode[i].F2); 46 if(t1!=t2){ 47 fa[t2]=t1; 48 if(inode[i].D[0]=='N'){ 49 dx[t2]=dx[inode[i].F1]-dx[inode[i].F2]; 50 dy[t2]=dy[inode[i].F1]-dy[inode[i].F2]+inode[i].L; 51 } 52 else if(inode[i].D[0]=='E'){ 53 dx[t2]=dx[inode[i].F1]-dx[inode[i].F2]+inode[i].L; 54 dy[t2]=dy[inode[i].F1]-dy[inode[i].F2]; 55 } 56 else if(inode[i].D[0]=='W'){ 57 dx[t2]=dx[inode[i].F1]-dx[inode[i].F2]-inode[i].L; 58 dy[t2]=dy[inode[i].F1]-dy[inode[i].F2]; 59 } 60 else if(inode[i].D[0]=='S'){ 61 dx[t2]=dx[inode[i].F1]-dx[inode[i].F2]; 62 dy[t2]=dy[inode[i].F1]-dy[inode[i].F2]-inode[i].L; 63 } 64 } 65 while(i==qnode[j].I-1){ 66 int tt1=finds(qnode[j].F1),tt2=finds(qnode[j].F2); 67 if(tt1!=tt2) ans[qnode[j].ind]=-1; 68 else 69 ans[qnode[j].ind]=abs(dx[qnode[j].F1]-dx[qnode[j].F2])+abs(dy[qnode[j].F1]-dy[qnode[j].F2]); 70 j++; 71 } 72 } 73 for(int i=0;i "%d\n",ans[i]); 74 return 0; 75 }