zoukankan      html  css  js  c++  java
  • 【poj 1984】&【bzoj 3362】Navigation Nightmare(图论--带权并查集)

    题意:平面上给出N个点,知道M个关于点X在点Y的正东/西/南/北方向的距离。问在刚给出一定关系之后其中2点的曼哈顿距离((x1,y1)与(x2,y2):l x1-x2 l+l y1-y2 l),未知则输出-1。

    解法:带权并查集。sx[x]表示x与其根结点的横坐标的差,sy[x]表示x与其根结点的纵坐标的差。}
    输入需要好好处理一下:1.我自定义(x,y,E)的x,y之间的横坐标差为正,W为负,N时的纵坐标差为正,S时为负;2.需要给询问排序,再一个个将关系存储下来。

    注意——我将x,y合并联盟时的关系式就偷懒按 【poj 1182】食物链(图论--带权并查集) 所提到的用方块图直接推,发现样例对了,还1A了,速度也比较快!(我代码也算是很清晰的吧)❀(๑╯◡╰๑)❀ 所以我真的向神犇求解啊!!

    P.S.我碰运气地没有完全推导、不负责任地打了ins( )里的式子,而对于这个hyc有另外的一种简单易懂的坐法:出现fx,x,fy,y,可知把fy附到x所在联盟下时,可以把 fy 和 y 颠倒相对位置,让输入的对于 x 和 y 的距离 d 可以直截了当地得到利用,赋值给“一身轻”的 y。

    1 int fy=ffind(y);
    2 sx[fy]=-sx[y],sy[fy]=-sy[y]; fa[fy]=y, fa[y]=x; 
    3 sx[y]=w[t][0]*d,sy[y]=w[t][0]*d;

    下面是我的完整代码——

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 using namespace std;
     7 
     8 const int N=40010,M=40010,K=10010;
     9 struct quiry{int x,y,t,id;}q[K];
    10 struct node{int x,y,d,t;}a[M];
    11 int n,m,k;
    12 char s[3];
    13 int fa[N],sx[N],sy[N],ans[K];
    14 int w[5][2]={{1,0},{0,-1},{-1,0},{0,1}};//ESWN,multi
    15 
    16 bool cmp(quiry x,quiry y) {return x.t<y.t;}
    17 int mabs(int x) {return x>0?x:-x;}
    18 int ffind(int x)
    19 {
    20     if (fa[x]!=x)
    21     {
    22       int fx=fa[x];
    23       fa[x]=ffind(fx);
    24       sx[x]+=sx[fx];
    25       sy[x]+=sy[fx];
    26     }
    27     return fa[x];
    28 }
    29 void ins(int x,int y,int d,int t)
    30 {
    31     int fx=ffind(x),fy=ffind(y);
    32     if (fx==fy) return;
    33     fa[fy]=fx;
    34     sx[fy]=w[t][0]*d+sx[x]-sx[y];//
    35     sy[fy]=w[t][1]*d+sy[x]-sy[y];//
    36 }
    37 int solve(int x,int y)
    38 {
    39     int fx=ffind(x),fy=ffind(y);
    40     if (fx!=fy) return -1;
    41     return mabs(sx[x]-sx[y])+mabs(sy[x]-sy[y]);
    42 }
    43 int main()
    44 {
    45     scanf("%d%d",&n,&m);
    46     for (int i=1;i<=m;i++)
    47     {
    48       scanf("%d%d%d%s",&a[i].x,&a[i].y,&a[i].d,s);
    49       if (s[0]=='E') a[i].t=0;
    50       if (s[0]=='S') a[i].t=1;
    51       if (s[0]=='W') a[i].t=2;
    52       if (s[0]=='N') a[i].t=3;
    53     }
    54     scanf("%d",&k);
    55     for (int i=1;i<=k;i++)
    56     {
    57       scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].t);
    58       q[i].id=i;
    59     }
    60     sort(q+1,q+1+k,cmp);
    61     for (int i=1;i<=n;i++) fa[i]=i,sx[i]=sy[i]=0;
    62     int t=0;
    63     for (int i=1;i<=k;i++)
    64     {
    65       while (t<q[i].t && t<m) {t++; ins(a[t].x,a[t].y,a[t].d,a[t].t);}
    66       ans[q[i].id]=solve(q[i].x,q[i].y);
    67     }
    68     for (int i=1;i<=k;i++) printf("%d
    ",ans[i]);
    69     return 0;
    70 }
  • 相关阅读:
    软件测试从业者,试用期生存指南(完整版)
    学测试,看视频?NONONO,除非这种情况
    vi / vim 字符替换详解
    Centos 下 mysql 安装过程
    Web测试到底是在测什么(资料合集)
    我花了两个小时,写了这份年终总结 。
    拒绝无效加班 !
    你离月薪30K还差哪些?
    从业十年分享:你应该知道的一些测试职业事实!
    别再TM跟我说找不到满意的工作!
  • 原文地址:https://www.cnblogs.com/konjak/p/6030978.html
Copyright © 2011-2022 走看看