zoukankan      html  css  js  c++  java
  • HDU 4916 Count on the path

    意甲冠军:

    考虑到一棵树,m询价  不要求回答每一次询价u和v通过在两个节点形成的最低等级点路径

    思路:

    一開始以为是LCA…  只是T了好几次…  后来发现不用LCA也可做

    考虑每一个询问u和v  假设他们的lca不是1  则1一定是答案  只是求lca会T  那么我们仅仅须要在遍历树的时候给节点染色  染的颜色就是1的儿子的颜色  假设x这个点在y的子树中(y是1的儿子)那么他的颜色就是y

    染完色后我们考虑答案是怎样构成的


    如图所看到的  答案即是  红色  蓝色  绿色的子树中节点的最小值  那么我们仅仅须要分开三部分求解就可以

    定义f[u][x]表示以u为根的子树中第x大的节点标号  这个能够通过树形dp求解  有了这个就能够解决绿色和红色的部分

    定义g[u]表示u节点上面到1的路径中旁側的子树的最小节点标号  即图中蓝色部分  也能够利用f做树形dp求解


    注意:

    题目中不让蓝色部分包括绿色部分  也不把绿色部分放在红色部分中考虑的原因就是u和v节点中的一个可能是1

    因为我写的是dfs  杭电会爆栈  所以记得加栈  并用C++提交


    代码:

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 1000010
    
    int f[N][4], g[N], col[N], head[N];
    int n, m, color, tot, ans;
    struct edge {
        int v, next;
    } ed[N * 2];
    
    int d(int a, int b) {
        if (a < b)
            return a;
        return b;
    }
    
    void add(int u, int v) {
        ed[tot].v = v;
        ed[tot].next = head[u];
        head[u] = tot++;
    }
    
    void dfs1(int u, int fa) {
        int i, v;
        if (u != 1)
            col[u] = color;
        for (i = head[u]; ~i; i = ed[i].next) {
            v = ed[i].v;
            if (u == 1)
                color = v;
            if (v != fa) {
                dfs1(v, u);
                f[u][3] = d(v, f[v][0]);
                sort(f[u], f[u] + 4);
            }
        }
    }
    
    void dfs2(int u, int fa) {
        if (fa != 1) {
            if (d(u, f[u][0]) != f[fa][0])
                g[u] = f[fa][0];
            else
                g[u] = f[fa][1];
            if (g[u] > g[fa])
                g[u] = g[fa];
        }
        int i, v;
        for (i = head[u]; ~i; i = ed[i].next) {
            v = ed[i].v;
            if (v != fa)
                dfs2(v, u);
        }
    }
    
    int main() {
        int i, j, u, v;
        while (~scanf("%d%d", &n, &m)) {
            for (i = 1; i <= n; i++) {
                f[i][0] = f[i][1] = f[i][2] = f[i][3] = g[i] = N;
                head[i] = -1;
            }
            col[1] = 1;
            tot = ans = 0;
            for (i = 1; i < n; i++) {
                scanf("%d%d", &u, &v);
                add(u, v);
                add(v, u);
            }
            dfs1(1, 1);
            dfs2(1, 1);
            for (i = 1; i <= m; i++) {
                scanf("%d%d", &u, &v);
                u ^= ans;
                v ^= ans;
                if (col[u] == col[v]) {
                    if (u == 1 || v == 1)
                        ans = 2;
                    else
                        ans = 1;
                } else {
                    if (u > v)
                        swap(u, v);
                    ans = min(f[v][0], min(g[u], g[v]));
                    if (u != 1) {
                        ans = min(ans, f[u][0]);
                        v = min(col[v], f[col[v]][0]);
                        u = min(col[u], f[col[u]][0]);
                        for (j = 0; j < 3; j++) {
                            if (f[1][j] != u && f[1][j] != v) {
                                ans = min(ans, f[1][j]);
                                break;
                            }
                        }
                    } else {
                        v = min(col[v], f[col[v]][0]);
                        for (j = 0; j < 3; j++) {
                            if (f[1][j] != v) {
                                ans = min(ans, f[1][j]);
                                break;
                            }
                        }
                    }
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Valgrind使用转载 Sanny.Liu
    Caffe模型读取 Sanny.Liu
    JNI动态库生成、编译、查看相关简易资料 Sanny.Liu
    GDB调试,转载一位大牛的东西 Sanny.Liu
    Android处理图片工具(转载) Sanny.Liu
    添加可点击的imagebottom,有个点击动画效果 Sanny.Liu
    去OpenCVManager,大部分为转载,仅当自己学习使用 Sanny.Liu
    转载: vim使用技巧 Sanny.Liu
    结构体数组初始化三种方法,转载 Sanny.Liu
    AsyncTask机制学习 Sanny.Liu
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4809315.html
Copyright © 2011-2022 走看看