• 图论:LCA-欧拉序


      1 #include<cmath>
      2 #include<vector>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 
      9 vector<int > g[40010];
     10 int len,a[80020],dep[80020],pos[80020][17],dp[80020][17],vis[80020],cnt[80020];
     11 
     12 void dfs(int u,int fa,int deep)
     13 {
     14     a[++len]=u;
     15     dep[len]=deep+1;
     16     if(!vis[u])
     17     {
     18         cnt[u]=len;
     19         vis[u]=1;
     20     }
     21     int sz=g[u].size();
     22     for(int i=0; i<sz; i++)
     23     {
     24         if(g[u][i]!=fa)
     25         {
     26             dfs(g[u][i],u,deep+1);
     27             a[++len]=u;
     28             dep[len]=deep+1;
     29         }
     30     }
     31 }
     32 
     33 int main()
     34 {
     35     int t;
     36     scanf("%d",&t);
     37     while(t--)
     38     {
     39         int n,m;
     40         len=0;
     41         memset(a,0,sizeof(a));
     42         memset(dep,0,sizeof(dep));
     43         memset(pos,0,sizeof(pos));
     44         memset(dp,0,sizeof(dp));
     45         memset(vis,0,sizeof(vis));
     46         memset(cnt,0,sizeof(cnt));
     47         scanf("%d%d",&n,&m);
     48         for(int i=1; i<=n; i++)
     49         {
     50             g[i].clear();
     51         }
     52         for(int i=1; i<=n-1; i++)
     53         {
     54             int from,to;
     55             scanf("%d%d",&from,&to);
     56             g[from].push_back(to);
     57             g[to].push_back(from);
     58         }
     59         dfs(1,0,0);
     60         printf("%d
    ",len);
     61         for(int i=1; i<=len; i++)
     62         {
     63             dp[i][0]=dep[i];
     64             pos[i][0]=i;
     65         }
     66         for(int j=1; j<=17; j++)
     67         {
     68             for(int i=1; i<=len; i++)
     69             {
     70                 if(i+(1<<(j-1))>=len)
     71                 {
     72                     break;
     73                 }
     74                 if(dp[i][j-1]>dp[i+(1<<(j-1))][j-1])
     75                 {
     76                     dp[i][j]=dp[i+(1<<(j-1))][j-1];
     77                     pos[i][j]=pos[i+(1<<(j-1))][j-1];
     78                 }
     79                 else
     80                 {
     81                     dp[i][j]=dp[i][j-1];
     82                     pos[i][j]=pos[i][j-1];
     83                 }
     84             }
     85         }
     86         for(int i=1; i<=m; i++)
     87         {
     88             int x,y;
     89             scanf("%d%d",&x,&y);
     90             int dx=cnt[x];
     91             int dy=cnt[y];
     92             if(dx>dy)
     93             {
     94                 swap(dx,dy);
     95                 swap(x,y);
     96             }
     97             int k=(int)(log((double)(dy-dx+1))/log(2.0));
     98             int p;
     99             if(dp[dx][k]>dp[dy-(1<<k)+1][k])
    100             {
    101                 p=pos[dy-(1<<k)+1][k];
    102             }
    103             else
    104             {
    105                 p=pos[dx][k];
    106             }
    107             printf("%d
    ",a[p]);
    108         }
    109     }
    110 
    111 }
  • 相关阅读:
    通过一个程序来理解PHP里面的抽象类【1】
    mycheckpoint 把玩手记
    Mysql 大量 unauthenticated user
    零基础学习Oracle 10G视频教程
    mysql show processlist命令 详解
    c# 中的事件
    c# 中方法签名 指的是?
    c# 中的索引
    介绍如何使用C#中的委托
    C# 语法学习笔记
  • 原文地址:https://www.cnblogs.com/aininot260/p/9681368.html
Copyright © 2020-2023  润新知