• spoj 913 Query on a tree II 倍增


     题意:给定一棵边带权树

    定义两种询问

    DIST a b : a b之间距离

    KTH a b k : a b之间的路径的第k个数

      1 #include<iostream>
    2 #include<cstring>
    3 #include<cmath>
    4 #include<cstdio>
    5 using namespace std;
    6 #define MAXN 10010
    7 struct node
    8 {
    9 int num,weight;
    10 node *next;
    11 };
    12 node *graph[MAXN];
    13 node memo[2*MAXN];
    14 int euler[2*MAXN],father[MAXN][20],d[MAXN],home[MAXN],Log[2*MAXN],length[MAXN];
    15 int sparse_table[2*MAXN][20],sparse_table_num[2*MAXN][20];
    16 int n,top;
    17 void my_log()
    18 {
    19 Log[1]=0;
    20 for(int i=2;i<2*MAXN;i++)
    21 Log[i]=Log[i/2]+1;
    22 }
    23 void add(int x,int y,int z)
    24 {
    25 node *p=&memo[top++];
    26 p->num=y; p->weight=z; p->next=graph[x]; graph[x]=p;
    27 p=&memo[top++];
    28 p->num=x; p->weight=z; p->next=graph[y]; graph[y]=p;
    29 }
    30 void dfs(int i,int deep,int fa,int w)
    31 {
    32 euler[++top]=i; home[i]=top;
    33 d[i]=deep; father[i][0]=fa; length[i]=length[fa]+w;
    34 for(int j=1;(1<<j)<d[i];j++)
    35 {
    36 father[i][j]=father[father[i][j-1]][j-1];
    37 }
    38 for(node *p=graph[i];p;p=p->next)
    39 if(p->num!=father[i][0])
    40 {
    41 dfs(p->num,deep+1,i,p->weight);
    42 euler[++top]=i;
    43 }
    44 }
    45 void build_sparse_table()
    46 {
    47 int i,j;
    48 for(i=1;i<=top;i++)
    49 {
    50 sparse_table[i][0]=d[euler[i]];
    51 sparse_table_num[i][0]=euler[i];
    52 }
    53 for(j=1;(1<<j)<=top;j++)
    54 {
    55 for(i=1;i<=top-(1<<j)+1;i++)
    56 {
    57 if(sparse_table[i][j-1]<sparse_table[i+(1<<(j-1))][j-1])
    58 {
    59 sparse_table[i][j]=sparse_table[i][j-1];
    60 sparse_table_num[i][j]=sparse_table_num[i][j-1];
    61 }
    62 else
    63 {
    64 sparse_table[i][j]=sparse_table[i+(1<<(j-1))][j-1];
    65 sparse_table_num[i][j]=sparse_table_num[i+(1<<(j-1))][j-1];
    66 }
    67 }
    68 }
    69 }
    70 int LCA(int x,int y)
    71 {
    72 if(x>y)
    73 {
    74 int t;
    75 t=x; x=y; y=t;
    76 }
    77 int z=Log[y-x+1];
    78 if(sparse_table[x][z]<sparse_table[y-(1<<z)+1][z])
    79 return sparse_table_num[x][z];
    80 else return sparse_table_num[y-(1<<z)+1][z];
    81 }
    82 int find(int x,int l)
    83 {
    84 int i=0;
    85 while(l>0)
    86 {
    87 if(l&1) x=father[x][i];
    88 i++;
    89 l>>=1;
    90 }
    91 return x;
    92 }
    93
    94 void solve()
    95 {
    96 char c[10];
    97 int x,y,z;
    98 int temp;
    99 while(1)
    100 {
    101 scanf("%s",c);
    102 if(c[0]=='D'&&c[1]=='O') break;
    103 if(c[0]=='D')
    104 {
    105 scanf("%d%d",&x,&y);
    106 temp=length[x]+length[y]-2*length[LCA(home[x],home[y])];
    107 printf("%d\n",temp);
    108 }
    109 else
    110 {
    111 scanf("%d%d%d",&x,&y,&z);
    112 int fa=LCA(home[x],home[y]);
    113 if(d[x]-d[fa]==z-1)
    114 {
    115 printf("%d\n",fa);
    116 }
    117 else if(d[x]-d[fa]>z-1)
    118 {
    119 printf("%d\n",find(x,z-1));
    120 }
    121 else printf("%d\n",find(y,d[x]+d[y]-2*d[fa]-z+1));
    122 }
    123 }
    124 printf("\n");
    125 }
    126
    127
    128
    129
    130 int main()
    131 {
    132 int T,i;
    133 int x,y,z;
    134 my_log();
    135 scanf("%d",&T);
    136 while(T--)
    137 {
    138 top=0;
    139 memset(graph,0,sizeof(graph));
    140 memset(father,0xff,sizeof(father));
    141 memset(length,0,sizeof(length));
    142 scanf("%d",&n);
    143 for(i=1;i<n;i++)
    144 {
    145 scanf("%d%d%d",&x,&y,&z);
    146 add(x,y,z);
    147 }
    148 top=0;
    149 length[1]=0;
    150 dfs(1,1,0,0);
    151 /*for(i=1;i<=n;i++)
    152 for(int j=0;j<=2;j++)
    153 {
    154 printf("%d %d %d %d\n",i,j,father[i][j],d[father[i][j]]);
    155 }*/
    156 build_sparse_table();
    157 solve();
    158 }
    159 return 0;
    160 }



  • 相关阅读:
    Windows Live Writer 语法高亮
    二十一、Java基础--------IO流之综合案例分析
    二十、Java基础--------IO流之其他对象
    十九、Java基础--------IO流之字节流
    十八、Java基础--------IO流体系以及字符流
    十七、Java基础---------集合框架之Map
    十六、Java基础---------集合框架之Set
    十五、Java基础---------集合框架体系以及List
    十四、Java基础---------String、StringBuffer、StringBuilder基本应用
    十三、Java基础---------多线程总结
  • 原文地址:https://www.cnblogs.com/myoi/p/2378990.html
Copyright © 2020-2023  润新知