分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

POJ-1984-Navigation Nightmare+带权并查集(中级

发布时间:2023-09-06 01:44责任编辑:郭大石关键词:暂无标签

传送门:Navigation Nightmare

参考:1:https://www.cnblogs.com/huangfeihome/archive/2012/09/07/2675123.html

参考:2:http://blog.csdn.net/tc_to_top/article/details/43447727

题意:先给出一个四方形的城市地图的全部信息,

  然后在只知道前k条信息的情况下,询问a,b之间的距离,若没连通,输出-1;

思路:

 首先,每次询问的K是按升序排列的(讨论版里神牛说的,还有就是题号很有深意);

     这道题让我对并查集有一个新的认识:根的代表性是非常强的!并查集里如果某个节点的改动会影响到整个并查集的所有节点,那么,在union_set的时候只需要改动根节点就可以了,当然,在find_set函数里要对所有节点进行更新(这相当于一种延时标记)。我们知道,find_set函数走了两条路,一条是前往根的路,一条是从跟返回的路,那么,如果发现根已经被改动,必须在从根返回的路上更新经过的所有节点。这在find_set函数里是可以实现的。

//样例7 61 6 13 E6 3 9 E3 5 7 S4 1 3 N2 4 20 W4 7 2 S31 6 11 4 32 6 6

模拟一遍样例,这里是执行完Find(1-7)以后的坐标
t = 1:   x[1] = 0,   y[1] = 0 
          x[6] = 13, y[6] = 0

t = 2:   x[1] = 0,   y[1] = 0
           x[6] = 13, y[6] = 0
           x[3] = 22, y[3] = 0

t = 3:   x[1] = 0,   y[1] = 0
           x[6] = 13, y[6] = 0
           x[3] = 22, y[3] = 0
           x[5] = 22, y[5] = -7

t = 4(换原点): 
           x[4] = 0,   y[4] = 0
           x[1] = 0,   y[1] = 3
           x[6] = 13, y[6] = 3
           x[3] = 22, y[3] = 3
           x[5] = 22, y[5] = -4

t = 5(换原点):
           x[2] = 0,   y[2] = 0
           x[4] = -20,y[4] = 0
           x[1] = -20,y[1] = 3
           x[6] = -7,  y[6] = 3
           x[3] = 2,   y[3] = 3
           x[5] = 2,   y[5] = -4

t = 6:   x[2] = 0,   y[2] = 0
           x[4] = -20,y[4] = 0
           x[1] = -20,y[1] = 3
           x[6] = -7,  y[6] = 3
           x[3] = 2,   y[3] = 3
           x[5] = 2,   y[5] = -4
           x[7] = -20,y[7] = -2

/* ???带权并查集;*/#include <cstdio>#include <algorithm>#include <iostream>#include <cstring>using namespace std;const int maxn = 40009;int n,m,fa[maxn],s[maxn],h[maxn];struct node{ ???int a,b,len; ???char c[5];}mp[maxn];void init(){ ???for(int i=1;i<=n;i++) ???????fa[i]=i; ???memset(s,0,sizeof(s)); ???memset(h,0,sizeof(h));}int ab(int x,int y){ ???if(x-y>0)return x-y; ???else return y-x;}int find(int x){ ???if(fa[x]==x)return x; ???int tmp = fa[x]; ???fa[x]=find(fa[x]); ???h[x] = h[x] + h[tmp]; ???// 从根回来的路上更新子节点 ???s[x] = s[x] + s[tmp]; ???return fa[x];}void uni(node t,int dx,int dy){ ???int px = find(t.a); ???int py = find(t.b); ???if(px==py)return; ???fa[px]=py; ???????????????// 随意合并 ???h[px] = h[t.b] - h[t.a] + dx;// 暂且只对根进行偏移 ???s[px] = s[t.b] - s[t.a] + dy; }int main(){ ???scanf("%d%d",&n,&m); ???init(); ???for(int i=0;i<m;i++) ???{ ???????scanf("%d%d%d%s",&mp[i].a, &mp[i].b, &mp[i].len, mp[i].c); ???} ???int q,k=0; ???scanf("%d",&q); ???while(q--) ???{ ???????int l,r,e; ???????scanf("%d%d%d",&l,&r,&e); ????????for(int i=k;i<e;i++) ????????{ ????????????int dx=0,dy=0; ????????????switch(mp[i].c[0]) ????????????{ ????????????????case ‘N‘:dy+=mp[i].len;break; ????????????????case ‘S‘:dy-=mp[i].len;break; ????????????????case ‘E‘:dx+=mp[i].len;break; ????????????????case ‘W‘:dx-=mp[i].len;break; ????????????} ????????????uni(mp[i],dx,dy); ????????} ????????k=e; ????????int pl=find(l),pr=find(r); ????????if(pl!=pr) ????????{ ????????????puts("-1"); ????????} ????????else ?????????{ ????????????printf("%d\n",ab(h[l],h[r])+ab(s[l],s[r])); ????????} ???} ???return 0;}

POJ-1984-Navigation Nightmare+带权并查集(中级

原文地址:https://www.cnblogs.com/ckxkexing/p/8510919.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved