【树形DP】 HDU 4916 Count on the path

通道

题意:一棵树,求不经过路径的最小标号

代码:

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

#define maxn 1005000
#define inf 0x3f3f3f3f

int child[maxn][4];
int subtree[maxn];
int path[maxn];
int fa[maxn];
int bel[maxn];
int que[maxn];
int qh, qt;
int n, nQ;

int head[maxn];
int nxt[maxn<<1];
int vv[maxn<<1];
int tot;

void add_Edge(int u,int v)
{
    vv[tot] = v; nxt[tot] = head[u]; head[u] = tot++;
}

void bfs()
{
    qh = qt = 0;
    que[qt++] = 1; fa[1] = -1;
    while (qh < qt){
        int u = que[qh++];
        for (int i = head[u]; ~i; i=nxt[i]){
            int v = vv[i];
            if (v == fa[u]) continue;
            fa[v] = u;
            que[qt++] = v;
        }
    }
    for (int i = 0; i <= n; ++i){
        for (int j = 0; j < 4; ++j){
            child[i][j] = inf;
        }
    }
    for (int i = n - 1; i >= 0; --i){
        int u = que[i]; subtree[u] = u;
        for (int j = head[u]; ~j; j=nxt[j]){
            int v = vv[j];
            if (v == fa[u]) continue;
            child[u][3] = subtree[v];
            sort(child[u], child[u] + 4);
        }
        subtree[u] = min(subtree[u], child[u][0]);
    }

    qh = qt = 0;
    for (int i = head[1]; ~i; i=nxt[i]){
        int v = vv[i];
        que[qt++] = v;
        bel[v] = subtree[v];
        path[v] = inf;
    }
    while (qh < qt){
        int u = que[qh++];
        for (int i = head[u]; ~i; i=nxt[i]){
            int v = vv[i];
            if (v == fa[u]) continue;
            bel[v] = bel[u];
            if (subtree[v] == child[u][0]){
                path[v] = min(path[u], child[u][1]);
            }
            else{
                path[v] = min(path[u], child[u][0]);
            }
            que[qt++] = v;
        }
        path[u] = min(path[u], child[u][0]);
    }
}

int query(int qu, int qv){
    if (qu > qv) swap(qu, qv);
    if (qu != 1 && bel[qu] == bel[qv]) return 1;
    int i = 0;
    while (child[1][i] == bel[qu] || child[1][i] == bel[qv]){
        i++;
    }
    int ret = qu == 1 ? path[qv] : min(path[qu], path[qv]);
    ret = min(ret, child[1][i]);
    return ret;
}

inline void scan(int &n)
{
    char cc;
    for (; cc = getchar(), cc<‘0‘ || cc>‘9‘;);
    n = cc - ‘0‘;
    for (; cc = getchar(), cc >= ‘0‘&&cc <= ‘9‘;)
        n = n * 10 + cc - ‘0‘;
}

int main()
{
    while (cin >> n >> nQ){
        tot = 0; memset(head, -1, sizeof(head));
        int ui, vi;
        for (int i = 0; i < n - 1; ++i){
            //scan(ui); scan(vi);
            scanf("%d%d", &ui, &vi);
            add_Edge(ui, vi);
            add_Edge(vi, ui);
        }
        bfs();
        int last = 0;
        for (int i = 0; i < nQ; ++i){
            //scan(ui); scan(vi);
            scanf("%d%d", &ui, &vi);
            ui ^= last; vi ^= last;
            printf("%d\n", last=query(ui, vi));
        }
    }
    return 0;
}

时间: 2024-11-13 08:14:42

【树形DP】 HDU 4916 Count on the path的相关文章

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 染完色后我们考虑答案是如何构成的 如图所示  答案即是  红色  蓝色  绿色的子树中节点的最小值  那么我们

fwt优化+树形DP HDU 5909

1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include <bits/stdc++.h> 6 // #include <iostream> 7 // #include <cstdio> 8 // #include <cstdlib> 9 // #include <algorithm> 10 // #inc

树形dp/hdu 1011 Starship Troopers

题意 有n个房子,1号为起点房子.每个房子里会消耗一定的士兵来获取一定的价值.现在有m个士兵,求问可以获得的最大价值 注意:走过的房子不能再走 注意2:若要消灭这个房子的bugs,必须全部消灭 分析 典型的树形dp,01背包,因为每个房子里要么全杀死bugs,要么一个不动,只有取或不取两种状态 设f[i][j]表示以i为根节点,消耗j个士兵所能获得的最大价值 则f[i][j]=max(f[son[i]][k] + f[i][j-k]); 答案为f[1][m] Accepted Code 1 /*

树形DP [HDU 2196] Computer

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3526    Accepted Submission(s): 1788 Problem Description A school bought the first computer some time ago(so this computer's id is 1). D

树形DP [HDU 1561] The more, The Better

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5506    Accepted Submission(s): 3274 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

(树形DP) hdu 3452

Bonsai Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 783    Accepted Submission(s): 395 Problem Description After being assaulted in the parking lot by Mr. Miyagi following the "All Valley Kar

(树形DP) hdu 1561

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5822    Accepted Submission(s): 3469 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物

(树形DP) hdu 1520

Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5619    Accepted Submission(s): 2580 Problem Description There is going to be a party to celebrate the 80-th Anniversary of the

[dp] hdu 4472 Count

意甲冠军: 鉴于n节点,满足子节点的相同的树节点号的同一层较少不同的形式. 思考: dp[i][j] 代表i节点.最后,一个层j方法节点 由于满足同层节点,所以j一层又一层必须是j 整数倍 所以就能得到兴许的状态 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include&