HEOI2014 大工程 虛樹 樹形DP

2021-10-02 22:09:55 字數 2263 閱讀 6413

還不錯,就是理解題意的時候理解的久了一些。題目中的距離實際上是每兩個點在原樹上的距離,而新建的結點是不會影響的,所以總的距離和是原樹上任意兩點的距離之和;最短距離呢,實際上就是最短邊權了;最長距離,實際上就是新構成虛樹上樹的直徑了,當然得是有效點的。

所以,構建虛樹,然後再進行乙個樹形dp就可以了。

#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f3f3f3f3f

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 1e6 + 7;

int n, q, qid[maxn << 1], log2[maxn];

struct build_graph

}edge[maxn << 1];

inline void addeddge(int u, int v, int w)

inline void _add(int u, int v, int w)

inline void init()

} old, now;

int dfn[maxn], tot, deep[maxn], fa[maxn][22];

inline bool cmp(int e1, int e2)

ll up_toroot[maxn] = ;

void pre_dfs(int u, int father)

}inline int lca(int u, int v)

if(u == v) return u;

for(int i=log2[n]; i>=0; i--)

}return fa[u][0];

}int stap[maxn << 1], stop;

inline void insert(int u)

int lca = lca(u, stap[stop]);

if(lca == stap[stop])

while(stop > 1 && dfn[lca] <= dfn[stap[stop - 1]])

if(lca ^ stap[stop])

stap[++stop] = u;

}bool used[maxn];

int k, siz[maxn];

ll down_min[maxn], down_max[maxn], ans_sum, ans_min, ans_max;

#define min_3(a, b, c) min(a, min(b, c))

#define max_3(a, b, c) max(a, max(b, c))

void dfs(int u)

if(used[u])

}void sum_dfs(int u)

now.head[u] = -1;

}inline void init()

log2[i] = k;

}}int main()

ans_sum = 0; ans_max = -inf; ans_min = inf;

dfs(stap[1]);

sum_dfs(stap[1]);

printf("%lld %lld %lld\n", ans_sum, ans_min, ans_max);

for(int i=1; i<=k; i++) used[qid[i]] = false;

}return 0;

}

P4103 HEOI2014 大工程 虛樹

虛樹板題一道。個人覺得這題比 消耗戰 更適合練板子 樹形dp更為簡單 說正解。注意到 p 2e 6 sum p le2e6 p 2 e6,這提示我們建一顆虛樹。建好後,2和3問就是求乙個樹上最短路,最長路,不再贅述。簡單說一下1,我們對於每一條邊統計有多少點對經過它。具體的,樹形dp的時候算出,即為...

P4103 HEOI2014 大工程 (虛樹)

觀察資料範圍是跟k有關的,因此我們考慮建立虛樹,對於維護三個值 總和就是常規的按每條路左右兩邊點數算貢獻,注意是特殊點的數量 之後我們維護mi i mx i 表示對於當前點,子樹中離他最近的特殊點在哪 includeusing namespace std typedef long long ll t...

P4103 HEOI2014 大工程 虛樹

戳這裡 虛樹板子題 首先有乙個 o qn 的暴力,就是對於每一次詢問,o n 的樹上 dp 我們統計一下每乙個點,它的子樹內離它最近 遠的關鍵點的距離,已經關鍵點的個數 對於第乙個詢問等價於 sum dep x dep y sum2 times dep lca 我們 dp 的時候順便統計一下每乙個點...