【bzoj3362-导航难题】带权并查集
2016-10-28 09:50
330 查看
题意:
约翰所在的乡村可以看做一个二维平面,其中有N 座牧场,每座牧场都有自己的坐标,编号为1
到N。牧场间存在一些道路,每条道路道路连接两个不同的牧场,方向必定平行于X 轴或Y轴。连通两座牧场之间的路径是唯一的。
突然间,约翰的导航仪失灵了,牧场的坐标记录全部消失了。所幸的是,约翰找到了表示道路的
数据,可以通过这些信息得知牧场间的相对位置。但贝西有急事,在约翰工作到一半的时候就要知道
一些牧场间的曼哈顿距离。这时,如果约翰能从找回的道路信息之间推算出答案,就会告诉贝西。请
你帮助约翰来回答贝西的问题吧。(x1,y1) 和(x2,y2) 间的曼哈顿距离定义为|x1 − x2| + |y1 − y2|。
– 如果字母是E、S、W 和N 中的一个,表示约翰找回了一条道路的信息,接下来有三个整
数x,y,和L,L 表示道路的长度,x,y表示道路连接的两个牧场,字母E、S、W、N
分别表示x在y的东、南、西、北方向。1 ≤x,y≤ N; 1 ≤ L ≤ 1000
1 ≤ N ≤ 40000; 1 ≤ Q ≤ 50000
题解:
对于每个点x,维护三个值:
fa[x]:x所在并查集的祖先,或者说是x的一个祖先。
f[x]:x到fa[x]的X坐标的差值,即X(x)-X(fa[x])
g[x]:x到fa[x]的Y坐标的差值,即Y(x)-Y(fa[x])
则并查集内任意亮点的x,y的曼哈顿距离为abs(f[x]-f[y])+abs(g[x]-g[y])
对于每条路径(x,y,len),我们可以把fa[x]连向y,则两个并查集合并。
设xx=fa[x],则fa[xx]=y。
f[xx]=X(xx)-X(y)=X(x)-X(y)-(X(x)-X(xx))=(+-)len-f[x]
g[xx]同理。
-1的情况:如果x和y不在同一个并查集内,则输出-1
代码:
约翰所在的乡村可以看做一个二维平面,其中有N 座牧场,每座牧场都有自己的坐标,编号为1
到N。牧场间存在一些道路,每条道路道路连接两个不同的牧场,方向必定平行于X 轴或Y轴。连通两座牧场之间的路径是唯一的。
突然间,约翰的导航仪失灵了,牧场的坐标记录全部消失了。所幸的是,约翰找到了表示道路的
数据,可以通过这些信息得知牧场间的相对位置。但贝西有急事,在约翰工作到一半的时候就要知道
一些牧场间的曼哈顿距离。这时,如果约翰能从找回的道路信息之间推算出答案,就会告诉贝西。请
你帮助约翰来回答贝西的问题吧。(x1,y1) 和(x2,y2) 间的曼哈顿距离定义为|x1 − x2| + |y1 − y2|。
– 如果字母是E、S、W 和N 中的一个,表示约翰找回了一条道路的信息,接下来有三个整
数x,y,和L,L 表示道路的长度,x,y表示道路连接的两个牧场,字母E、S、W、N
分别表示x在y的东、南、西、北方向。1 ≤x,y≤ N; 1 ≤ L ≤ 1000
1 ≤ N ≤ 40000; 1 ≤ Q ≤ 50000
题解:
对于每个点x,维护三个值:
fa[x]:x所在并查集的祖先,或者说是x的一个祖先。
f[x]:x到fa[x]的X坐标的差值,即X(x)-X(fa[x])
g[x]:x到fa[x]的Y坐标的差值,即Y(x)-Y(fa[x])
则并查集内任意亮点的x,y的曼哈顿距离为abs(f[x]-f[y])+abs(g[x]-g[y])
对于每条路径(x,y,len),我们可以把fa[x]连向y,则两个并查集合并。
设xx=fa[x],则fa[xx]=y。
f[xx]=X(xx)-X(y)=X(x)-X(y)-(X(x)-X(xx))=(+-)len-f[x]
g[xx]同理。
-1的情况:如果x和y不在同一个并查集内,则输出-1
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 #include<set> 9 using namespace std; 10 11 const int N=40010; 12 int n,m,Q,f ,g ,fa ,ans ; 13 struct node{ 14 char s[10]; 15 int x,y,len; 16 }a ; 17 struct nod{ 18 int t,x,y,id; 19 }q ; 20 int myabs(int x){return x>0 ? x:-x;} 21 bool cmp(nod x,nod y){return x.t<y.t;} 22 23 int findfa(int x) 24 { 25 if(fa[x]!=x) 26 { 27 int y=fa[x]; 28 fa[x]=findfa(y); 29 f[x]=f[x]+f[y]; 30 g[x]=g[x]+g[y]; 31 } 32 return fa[x]; 33 } 34 35 int main() 36 { 37 // freopen("a.in","r",stdin); 38 freopen("navigate.in","r",stdin); 39 freopen("navigate.out","w",stdout); 40 scanf("%d%d",&n,&m); 41 int x,y,len,xx,yy; 42 for(int i=1;i<=n;i++) fa[i]=i; 43 memset(f,0,sizeof(f)); 44 memset(g,0,sizeof(g)); 45 for(int i=1;i<=m;i++) 46 { 47 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].len); 48 scanf("%s",a[i].s); 49 } 50 scanf("%d",&Q); 51 for(int i=1;i<=Q;i++) 52 { 53 scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].t); 54 q[i].id=i; 55 } 56 sort(q+1,q+1+Q,cmp); 57 int j=1; 58 for(int i=1;i<=m;i++) 59 { 60 x=a[i].x,y=a[i].y,len=a[i].len; 61 xx=findfa(x),yy=findfa(y); 62 if(xx==yy) continue; 63 fa[xx]=y; 64 if(a[i].s[0]=='E') 65 { 66 f[xx]=len-f[x]; 67 g[xx]=-g[x]; 68 } 69 if(a[i].s[0]=='W') 70 { 71 f[xx]=-len-f[x]; 72 g[xx]=-g[x]; 73 } 74 if(a[i].s[0]=='N') 75 { 76 f[xx]=-f[x]; 77 g[xx]=len-g[x]; 78 } 79 if(a[i].s[0]=='S') 80 { 81 f[xx]=-f[x]; 82 g[xx]=-len-g[x]; 83 } 84 while(j<=Q && q[j].t==i) 85 { 86 x=q[j].x,y=q[j].y; 87 xx=findfa(x),yy=findfa(y); 88 if(xx!=yy) ans[q[j].id]=-1;//printf("-1\n"); 89 else ans[q[j].id]=myabs(f[x]-f[y])+myabs(g[x]-g[y]);//printf("%d\n",myabs(f[x]-f[y])+myabs(g[x]-g[y])); 90 j++; 91 } 92 } 93 for(int i=1;i<=Q;i++) printf("%d\n",ans[i]); 94 return 0; 95 }
相关文章推荐
- bzoj 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 带权并查集
- BZOJ_3362_[Usaco2004 Feb]Navigation Nightmare 导航噩梦_并查集
- bzoj 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦(加权并查集)
- 带权并查集【bzoj3362】: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
- bzoj3362[Usaco2004 Feb]Navigation Nightmare 导航噩梦(带权并查集)
- [BZOJ3362][Usaco2004 Feb]Navigation Nightmare 导航噩梦(加权并查集)
- BZOJ 3362 Navigation Nightmare 带权并查集
- bzoj3362[Usaco2004 Feb]Navigation Nightmare 导航噩梦
- POJ 1984/BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
- BZOJ 3362 POJ 1984 Navigation Nightmare 带权并查集
- [删边最短路 并查集||线段树] BZOJ 2725 [Violet 6]故乡的梦 & 4400 tjoi2012 桥
- BZOJ 3237 浅谈CDQ分治+带撤销并查集
- 【BZOJ】3674: 可持久化并查集加强版
- [上下界网络流 二分] BZOJ 3698 XWW的难题
- BZOJ 4579 Closing the Farm - 并查集
- [并查集]BZOJ 1050——[HAOI2006]旅行comf
- BZOJ 1015 逆求 并查集
- [BZOJbegin][NOIP十连测热身赛]星球联盟(并查集)
- BZOJ 4668: 冷战 并查集
- BZOJ 3698(XWW的难题-上下界网络流+经典建模)