zoukankan      html  css  js  c++  java
  • CF232C Doe Graphs

      传送门

    Solution:  (不理解时对着图研究一下就清楚啦!!!)

    sm[i]为|D(i)|  (x,y,n)为x,y在D(n)中的最短路

    已知sm[i-1]+1为D(i)的割点

    于是x-y的最短路就可以分为三种情况:

    • x<sm[n-1]+1&&y>=sm[n-1]+1 
    • x<sm[n-1]+1&&y<sm[n-1]+1
    • x>=sm[n-1]+1&&y>=sm[n-1]+1

    下面我们就来讨论这三种情况

    • x在图D(n-1)上,y在图D(n-2)上,它们的最短路必过割点sm[n-1]+1

      我们只要分别求解x,y到割点的最短路即可

      y到割点的最短路即为(1,y-sm[n-1],n-2)

      x到割点的最短路却有两种可能 (1,x,n-1)+1或(x,sm[n-1],n-1)+1 这两种情况取小即可

    • x,y都在图D(n-1)上

      一定要注意这里 x-y的最短路并不一定局限于D(n-1) 还有可能经过割点

      所以这里有两种情况:(x,y,n-1)

        又有两种经过割点的方式: (1,x,n-1)+(y,sm[n-1],n-1)+2 和 (1,y,n-1)+(x,sm[n-1],n-1)+2

        同样取小即可

    • x,y都在图D(n-2)上

      是最简单的一种情况啊,为(x,y,n-2)

      但是如果这样子递归下去是会TLE的,所以我们要优化一下

      发现只要求出图D(i)中x,y点到1和sm[i]的最短路就可以了

      于是预处理出就可以了

      d1[i]为(1,x,i) d2[i]为(x,sm[i],i) d3[i]为(1,y,i) d4[i]为(y,sm[i],i)

      pre函数看图研究一下就可以理解啦

      

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define R register
     5 #define go(i,a,b) for(R int i=a;i<=b;i++)
     6 #define ll long long
     7 #define M 105
     8 using namespace std;
     9 ll rd()
    10 {
    11     ll x=0,y=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    14     return x*y;
    15 }
    16 ll T,n,sm[M],d[M],d1[M],d2[M],d3[M],d4[M];
    17 void pre(ll x,ll nw,ll t1[],ll t2[])
    18 {
    19     if(nw==0) return ;
    20     if(nw==1) {t1[1]=(x==2);t2[1]=(x==1);return ;}
    21     if(x<=sm[nw-1])
    22     {
    23         pre(x,nw-1,t1,t2);
    24         t1[nw]=min(t1[nw-1],t2[nw-1]+2);
    25         t2[nw]=min(t1[nw-1],t2[nw-1])+d[nw-2]+1;
    26     }
    27     else
    28     {
    29         pre(x-sm[nw-1],nw-2,t1,t2);
    30         t1[nw]=t1[nw-2]+1;
    31         t2[nw]=t2[nw-2];
    32     }
    33 }
    34 ll qy(ll x,ll y,ll nw)
    35 {
    36     if(nw<=1) return x!=y;
    37     if(x<sm[nw-1]+1&&y>=sm[nw-1]+1) return min(d1[nw-1],d2[nw-1])+d3[nw-2]+1;
    38     if(x<sm[nw-1]+1&&y<sm[nw-1]+1) return min(qy(x,y,nw-1),min(d1[nw-1]+d4[nw-1],d2[nw-1]+d3[nw-1])+2);
    39     return qy(x-sm[nw-1],y-sm[nw-1],nw-2);
    40 }
    41 int main()
    42 {
    43     freopen("1.in","r",stdin);
    44     freopen("1.out","w",stdout);
    45     T=rd();n=rd();n=min(n,(ll)80);
    46     sm[0]=1;sm[1]=2;d[0]=0;d[1]=1;//d[i]表示D(i)的1到sm[i]结点的最短距离
    47     go(i,2,n) sm[i]=sm[i-1]+sm[i-2],d[i]=d[i-2]+1;n=min(n,(ll)80);
    48     while(T--)
    49     {
    50         ll x=rd(),y=rd();if(x>y)swap(x,y);
    51         pre(x,n,d1,d2);pre(y,n,d3,d4);
    52         printf("%lld
    ",qy(x,y,n));
    53     }
    54     return 0;
    55 }
    View Code

    后:

    真的没那么难啊 仔细分析细心一点就没有问题啦

    然而 我还是调了一晚上qwq 因为longlong 要哭了...

    如果哪里不懂一定要问我 因为可能我也不懂那我就要感谢你发现我没懂的地方啦

    然后我们可以一起研究啦啦啦

    光伴随的阴影
  • 相关阅读:
    CUDA和cudnn的环境变量设置问题
    zsh-Ubuntu更实用终端
    应用安全
    应用安全
    应用安全
    操作系统
    应用安全
    应用安全
    操作系统
    密码学
  • 原文地址:https://www.cnblogs.com/forward777/p/10372248.html
Copyright © 2011-2022 走看看