HDU 4916 Count on the path

來源:互聯網
上載者:User

標籤:hdu   dp   

題意:

給定一棵樹和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 1000010int 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\n", ans);        }    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.