• HDOJ 4008Parent and son解题报告


    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4008

    题意很简单,给出一棵树,找出以x节点为根节点的情况下,y节点的最小儿子节点和最小子孙节点,每次进行一次搜索肯定是不行的,所以我们考虑只进行一次搜索,利用得到的结论去找到在其他情况下的解,先在以1为根节点的树中进行一遍深度优先搜索,记录下son[u][0](以u为根节点的子树中标号最小的子节点点)son[u][1](以u为根节点的树中标号次小的子节点)因为在选定不同的根节点导致图旋转的过程中,这两个节点最多有一个会变成u的父节点,所以直接确定另一个就可以了。low[u][0](以u为节点的子树中,标号最小的子孙节点),low[u][1](以u为根的所有的子树中所有low[v][0]的次小值,注意仔细理解这句话的意义,因为图旋转的过程中最多会有一棵子树在u节点的上方,所以同样可以确定另一个),具体的有一些细节的实现可以看代码

    View Code
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #define N 100005
      5 #define inf 0x7fffffff
      6 using namespace std;
      7 int son[N][2],low[N][2];
      8 int pre[N];
      9 int head[N],cnt;
     10 struct node
     11 {
     12     int v,next;
     13 };
     14 node e[N*2];
     15 bool used[N];
     16 int min(int a,int b)
     17 {
     18     return a<b?a:b;
     19 }
     20 void add(int u,int v)
     21 {
     22     e[cnt].v=v,e[cnt].next=head[u],head[u]=cnt++;
     23     e[cnt].v=u,e[cnt].next=head[v],head[v]=cnt++;
     24 }
     25 void init()
     26 {
     27     memset(head,-1,sizeof(head));
     28     memset(pre,-1,sizeof(pre));
     29     memset(used,0,sizeof(used));
     30     cnt=0;
     31     int i;
     32     for(i=0;i<N;i++)
     33     {
     34         son[i][0]=son[i][1]=inf;
     35         low[i][0]=low[i][1]=inf;
     36     }
     37 }
     38 void dfs(int u,int f)
     39 {
     40     int i,v;
     41     pre[u]=f;
     42     used[u]=true;
     43     for(i=head[u];i>=0;i=e[i].next)
     44     {
     45         v=e[i].v;
     46         if(used[v])
     47         continue;
     48         if(v!=f)
     49         dfs(v,u);
     50         if(v<son[u][1])
     51         son[u][1]=v;
     52         if(son[u][0]>son[u][1])
     53         swap(son[u][0],son[u][1]);
     54         int minn=low[v][0]<v?low[v][0]:v;
     55         if(minn<low[u][1])
     56         low[u][1]=minn;
     57         if(low[u][1]<low[u][0])
     58         swap(low[u][1],low[u][0]);
     59     }
     60 }
     61 int find(int x,int y)
     62 {
     63     while(pre[x]!=x)
     64     {
     65         if(pre[x]==y)
     66         return x;
     67         x=pre[x];
     68     }
     69     return 0;
     70 }
     71 int main()
     72 {
     73     int t,n,x,y,q,ans1,ans2,temp,i;
     74     scanf("%d",&t);
     75     while(t--)
     76     {
     77         scanf("%d%d",&n,&q);
     78         init();
     79         for(i=1;i<n;i++)
     80         {
     81             scanf("%d%d",&x,&y);
     82             add(x,y);
     83         }
     84         dfs(1,1);
     85         for(i=1;i<=q;i++)
     86         {
     87             scanf("%d%d",&x,&y);
     88             ans1=ans2=inf;
     89             temp=find(x,y);
     90             if(temp==0)
     91             {
     92                 ans1=son[y][0];
     93                 ans2=low[y][0];
     94             }
     95             else
     96             {
     97                 if(y!=1)
     98                 {
     99                     if(temp==son[y][0])
    100                     ans1=min(son[y][1],pre[y]);
    101                     else
    102                     ans1=min(son[y][0],pre[y]);
    103                     ans2=1;//这个可以直接确定
    104                 }
    105                 else
    106                 {
    107                     if(temp==son[y][0])
    108                     ans1=son[y][1];
    109                     else
    110                     ans1=son[y][0];
    111                     if(low[temp][0]==low[y][0]||low[y][0]==temp)//选择最小值次小的那棵子树
    112                     ans2=low[y][1];
    113                     else
    114                     ans2=low[y][0];
    115                 }
    116             }
    117             if(ans1==inf||ans2==inf)
    118             printf("no answers!\n");
    119             else
    120             printf("%d %d\n",ans1,ans2);
    121         }
    122         printf("\n");
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    云级Keyvalue数据库大比较
    如何诊断ORA125XX连接问题
    Oracle Internal Event:10235 Heap Checking诊断事件
    Oracle Database 11g R2 在Oracle Linux 6上获得认证
    一张图帮你搞懂oracle UGA User Global Area的概念
    Oracle Buffer Cache Chain图解
    ORA04036: 实例使用的 PGA 内存超出 PGA_AGGREGATE_LIMIT
    如何诊断ASMLIB故障
    Oracle RDBMS Server 11gR2 Preinstall RPM For Oracle Linux 6
    图解Oracle Buffer Cache LRU List
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2671898.html
Copyright © 2020-2023  润新知