[LCA] POJ 1330

来源:互联网 发布:铣床和车床编程区别 编辑:程序博客网 时间:2024/06/05 10:41

最基本的LCA啦~
用二分的方法做的
和书上代码一模一样。。。

#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>using namespace std;const int max_n = 10000;const int max_log_n = 14; // (1 << max_log_n) > max_nint n;int root; //根节点int dep[ max_n ];int par[ max_log_n ][ max_n ]; //向上走2^k步所到的节点vector<int> child[ max_n ]; //图的邻接表void dfs ( int u, int p, int d ) {    dep[ u ] = d;    for ( int i = 0; i < int( child[ u ].size () ); i++ ) {        int v = child[ u ][ i ];        if ( v != p ) {            dfs ( v, u, d + 1 );        }    }}void build () {    // 预处理 par[0][u] and dep[u]    dfs ( root, -1, 0 );    // par[i][u]    for ( int i = 0; i + 1 < max_log_n; i++ ) {        for ( int u = 0; u < n; u++ ) {            if ( par[ i ][ u ] == -1 )                par[ i + 1 ][ u ] = -1;            else                par[ i + 1 ][ u ] = par[ i ][ par[ i ][ u ] ];        }    }}int lca ( int u, int v ) {    if ( dep[ u ] > dep[ v ] )        swap ( u, v );    // u v 走到同一深度    int diff = dep[ v ] - dep[ u ];    for ( int i = 0; i < max_log_n; i++ ) {        if ( diff & ( 1 << i ) ) {            v = par[ i ][ v ];        }    }    if ( u == v )        return u;    //二分法计算LCA    for ( int i = max_log_n - 1; i >= 0; i-- ) {        if ( par[ i ][ u ] != par[ i ][ v ] ) {            u = par[ i ][ u ];            v = par[ i ][ v ];        }    }    return par[ 0 ][ u ];}int main () {    int tc;    scanf ( "%d", &tc );    while ( tc-- ) {        scanf ( "%d", &n );        //一个新东西        fill ( dep, dep + n, -1 );        for ( int i = 0; i < max_log_n; i++ )            fill ( par[ i ], par[ i ] + n, -1 );        for ( int i = 0; i < n; i++ )            child[ i ].clear ();        for ( int i = 0; i < n - 1; i++ ) {            int u, v;            scanf ( "%d %d", &u, &v );            u--;            v--;            par[ 0 ][ v ] = u;            child[ u ].push_back ( v );        }        root = -1;        for ( int u = 0; u < n; u++ ) {            if ( par[ 0 ][ u ] == -1 ) {                root = u;                break;            }        }        build ();        int u, v;        scanf ( "%d %d", &u, &v );        u--;        v--;        printf ( "%d\n", lca ( u, v ) + 1 );    }    return 0;}