zoukankan      html  css  js  c++  java
  • 旅行计划

      1 #include <cmath>
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <string>
      6 #include <cstdlib>
      7 #include <vector>
      8 #include <algorithm>
      9 #define mp make_pair
     10 #define fi first
     11 #define se second
     12 
     13 using namespace std;
     14 
     15 typedef pair<int,int> PII;
     16 const int MAXN=100005;
     17 const int INF=1000000000;
     18 
     19 struct Point{
     20     int x,y,num;
     21     friend bool operator < (const Point &a,const Point &b)
     22     {
     23         if (a.x!=b.x) return a.x<b.x;
     24         return a.y<b.y;
     25     }
     26 }pnt[MAXN];
     27 
     28 struct E{
     29     int a,b,w;
     30     E(void){}
     31     E(int _a,int _b,int _w):a(_a),b(_b),w(_w){}
     32     friend bool operator < (const E &a,const E &b)
     33     {
     34         return a.w<b.w;
     35     }
     36 }e[MAXN*4];
     37 int en;
     38 
     39 struct G{
     40     int to,next,d;
     41 }g[MAXN*2];
     42 int gn,start[MAXN];
     43 
     44 inline void Add(int a,int b,int d)
     45 {
     46     gn++,g[gn].to=b,g[gn].d=d,g[gn].next=start[a],start[a]=gn;
     47 }
     48 
     49 int n,m;
     50 int fa[MAXN];
     51 int ffa[20][MAXN];
     52 int dis[20][MAXN];
     53 int a[MAXN],b[MAXN];
     54 PII c[MAXN];
     55 int Log[MAXN];
     56 int dep[MAXN];
     57 
     58 inline void Update(int x,PII v)
     59 {
     60     for (int i=x;i<=n;i+=i&(-i)) c[i]=min(c[i],v);
     61 }
     62 
     63 inline PII Query(int x)
     64 {
     65     PII res=mp(INF,-1);
     66     for (int i=x;i;i-=i&(-i)) res=min(res,c[i]);
     67     return res;
     68 }
     69 
     70 int getfa(int x)
     71 {
     72     if (fa[x]!=x) fa[x]=getfa(fa[x]);
     73     return fa[x];
     74 }
     75 
     76 void merge(int x,int y)
     77 {
     78     fa[getfa(x)]=getfa(y);
     79 }
     80 
     81 inline int LCA(int p,int q)
     82 {
     83     if (dep[p]<dep[q]) swap(p,q);
     84     int x=dep[p]-dep[q];
     85     for (int i=0;i<=Log[x];i++)
     86         if (x&(1<<i)) p=ffa[i][p];
     87     for (int i=Log[n];i>=0;i--)
     88         if (ffa[i][p]!=ffa[i][q]) p=ffa[i][p],q=ffa[i][q];
     89     if (p==q) return p;
     90     return ffa[0][p];
     91 }
     92 
     93 inline int Query(int p,int q)
     94 {
     95     int x=dep[p]-dep[q];
     96     int res=0;
     97     for (int i=0;i<=Log[x];i++)
     98         if (x&(1<<i)) res=max(res,dis[i][p]),p=ffa[i][p];
     99     return res;
    100 }
    101 
    102 void Init()
    103 {
    104     scanf("%d",&n);
    105     for (int i=1;i<=n;i++)
    106     {
    107         scanf("%d%d",&pnt[i].x,&pnt[i].y);
    108         pnt[i].num=i;
    109     }
    110 }
    111 
    112 void BuildMST()
    113 {
    114     for (int dir=1;dir<=4;dir++)
    115     {
    116         if (dir==2||dir==4)
    117             for (int i=1;i<=n;i++) swap(pnt[i].x,pnt[i].y);
    118         if (dir==3)
    119             for (int i=1;i<=n;i++) pnt[i].x=-pnt[i].x;
    120         sort(pnt+1,pnt+n+1);
    121         for (int i=1;i<=n;i++) a[i]=b[i]=pnt[i].x-pnt[i].y;
    122         sort(b+1,b+n+1);
    123         int nq=unique(b+1,b+n+1)-(b+1);
    124         for (int i=1;i<=n;i++)
    125         {
    126             a[i]=lower_bound(b+1,b+nq+1,a[i])-b;
    127             c[i]=mp(INF,-1);
    128         }
    129         for (int i=n;i;i--)
    130         {
    131             int now=Query(a[i]).se;
    132             if (now!=-1) e[++en]=E(pnt[i].num,pnt[now].num,pnt[now].x+pnt[now].y-pnt[i].x-pnt[i].y);
    133             Update(a[i],mp(pnt[i].x+pnt[i].y,i));
    134         }
    135     }
    136     for (int i=1;i<=n;i++) fa[i]=i;
    137     sort(e+1,e+en+1);
    138     for (int i=1;i<=en;i++)
    139     {
    140         if (getfa(e[i].a)==getfa(e[i].b)) continue;
    141         merge(e[i].a,e[i].b);
    142         Add(e[i].a,e[i].b,e[i].w);
    143         Add(e[i].b,e[i].a,e[i].w);
    144     }
    145 }
    146 
    147 void BuildTree()
    148 {
    149     static int qu[MAXN];
    150     static bool vis[MAXN];
    151     int head=0,tail=1;
    152     qu[0]=1;
    153     vis[1]=true;
    154     while (head!=tail)
    155     {
    156         int p=qu[head++];
    157         for (int i=start[p];i;i=g[i].next)
    158         {
    159             int v=g[i].to,d=g[i].d;
    160             if (vis[v]) continue;
    161             vis[v]=true;
    162             dep[v]=dep[p]+1;
    163             dis[0][v]=d;
    164             ffa[0][v]=p;
    165             qu[tail++]=v;
    166         }
    167     }
    168     Log[0]=-1;
    169     for (int i=1;i<=n;i++) Log[i]=Log[i>>1]+1;
    170     for (int i=1;i<=Log[n];i++)
    171         for (int j=1;j<=n;j++)
    172         {
    173             ffa[i][j]=ffa[i-1][ffa[i-1][j]];
    174             dis[i][j]=max(dis[i-1][j],dis[i-1][ffa[i-1][j]]);
    175         }
    176 }
    177 
    178 void Solve()
    179 {
    180     scanf("%d",&m);
    181     while (m--)
    182     {
    183         int p,q,lca;
    184         scanf("%d%d",&p,&q);
    185         lca=LCA(p,q);
    186         printf("%d
    ",max(Query(p,lca),Query(q,lca)));
    187     }
    188 }
    189 
    190 int main()
    191 {
    192     freopen ("plan.in","r",stdin);
    193     freopen ("plan.out","w",stdout);
    194     Init();
    195     BuildMST();
    196     BuildTree();
    197     Solve();
    198     return 0;
    199 }

    ***考试的时候有一种预感这个和树有关系,可素我不会写树哇,于是乎我就开始另辟蹊径(==胡乱打代码),算每一个点到另一个点的最小值并保存这个点的位置,把这个点当做下一次起点,直到它可以一直绕到终点。。为了防止绕不到我还固定如果绕不到就直接求起点和终点的距离。。。可素可素。。。爆零了,(╥╯^╰╥)

    ***果然题解是和树有关,还是我当初唯一听懂的树剖(emmm可能是听懂了吧。。反正当初没在意代码,能听懂意思我就很开心了。。于是乎现在悲催了),接下来附上当初我对树剖的理解叭

     

    对于每个点记录他的深度是多少

    表示处于链最顶端是谁

    会经过Log n

    步骤

    1.比较深度,(每个点为根树的大小)

    2.看这两个点所在顶端是否一样

    不一样

    深度较大的点指向他链顶端的父亲

    那就是求自己点和父亲点的链数量

    随便挑一个点作为父亲

    3.移位

    移到他所在链的顶端的父亲的点

    在移到父亲的点

    直到俩父亲点在同一个链上面

    上面的点为答案

     **

    由大到小成为一个链

    有的倒霉孩子就一个点一个连

    预处理完毕

    进行查询

    求最近公共祖先

     

    说明当初脑子还是正常的吧。。。我可能老了。。记忆力不好了。。。。假如这道题不是树剖。我写的这坨会不会很尴尬。。。

  • 相关阅读:
    一次Oracle数据迁移
    mysql Error Handling and Raising in Stored Procedures
    expdp ORA-39213
    RHEL 6.4 64bit kettle5.01导入xlsx格式的excel时报错
    Oracle表空间传输测试
    oracle expdp 无法导出SYS下特定TABLE
    Oracle wrap 测试的一些细节问题
    论文-CondenseNet: An Efficient DenseNet using Learned Group Convolutions
    SystemVerilog-断言
    推挽输出和开漏输出
  • 原文地址:https://www.cnblogs.com/rax-/p/8606519.html
Copyright © 2011-2022 走看看