题目链接:http://poj.org/problem?id=1984
题目大意:有n个点,在平面上位于坐标点上,给出m关系F1 F2 L D ,表示点F1往D方向走L距离到点F2,然后给出一系列询问F1 F2 I,表示在第I个关系给出后询问F1和F2两点间的曼哈顿距离,或者未知则输出-1。
解题思路:带权并查集,但是要开二维,val[][0]表示上下(南北)方向的偏移量,val[][1]表示左右(东西)方向的偏移量,然后一直更新就好,记得两个维度都要一起更新。
代码:
1 #include<iostream> 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=5e4+5; 8 int root[N],val[N][2],res[N];//val[][]用来记录权值,val[][0]表示南北方向的偏移量,val[][1]表示东西方向的偏移量 9 10 struct node{ 11 int a,b,len; 12 char det[5]; 13 }arr[N]; 14 15 struct Node{ 16 int a,b,id; 17 Node(){} 18 Node(int l,int r,int c){ 19 a=l; 20 b=r; 21 id=c; 22 } 23 }; 24 vector<Node>v[N]; 25 26 int find(int x){ 27 if(root[x]==x) 28 return x; 29 int tmp=find(root[x]); 30 val[x][0]+=val[root[x]][0]; 31 val[x][1]+=val[root[x]][1]; 32 return root[x]=tmp; 33 } 34 35 int main(){ 36 int n,m; 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=n;i++){ 39 root[i]=i; 40 } 41 for(int i=1;i<=m;i++){ 42 scanf("%d%d%d%s",&arr[i].a,&arr[i].b,&arr[i].len,arr[i].det); 43 } 44 int q; 45 scanf("%d",&q); 46 for(int i=1;i<=q;i++){ 47 int a,b,num; 48 scanf("%d%d%d",&a,&b,&num); 49 v[num].push_back(Node(a,b,i)); 50 } 51 52 for(int i=1;i<=m;i++){ 53 int a=arr[i].a,b=arr[i].b,len=arr[i].len; 54 int t1=find(a); 55 int t2=find(b); 56 if(t1!=t2){ 57 root[t2]=t1; 58 if(arr[i].det[0]=='N'){ 59 val[t2][0]=val[a][0]-val[b][0]+len;//val[t2][0]+val[b][0]=val[a][0]+len即a点向北走len距离到b点 60 val[t2][1]=val[a][1]-val[b][1];//东西方向没有发生偏移 61 } 62 if(arr[i].det[0]=='S'){ 63 val[t2][0]=val[a][0]-val[b][0]-len;//val[t2][0]+val[b][0]=val[a][0]+len即a点向南走len距离到b点 64 val[t2][1]=val[a][1]-val[b][1]; 65 } 66 if(arr[i].det[0]=='W'){ 67 val[t2][1]=val[a][1]-val[b][1]-len;//同理 68 val[t2][0]=val[a][0]-val[b][0]; 69 } 70 if(arr[i].det[0]=='E'){ 71 val[t2][1]=val[a][1]-val[b][1]+len; 72 val[t2][0]=val[a][0]-val[b][0]; 73 } 74 } 75 for(int j=0;j<v[i].size();j++){ 76 a=v[i][j].a; 77 b=v[i][j].b; 78 t1=find(a); 79 t2=find(b); 80 if(t1!=t2)//两点不在同一个并查集中则两点间没有通路 81 res[v[i][j].id]=-1; 82 else 83 res[v[i][j].id]=abs(val[a][0]-val[b][0])+abs(val[a][1]-val[b][1]); 84 } 85 } 86 for(int i=1;i<=q;i++){ 87 printf("%d ",res[i]); 88 } 89 return 0; 90 }