3257: 樹的難題
time limit: 10 sec memory limit: 128 mb
submit: 56 solved: 39
[submit][status][discuss]
description
給出乙個無根樹。樹有n個點,邊有權值。每個點都有顏色,是黑色、白色、
灰色這三種顏色之一,稱為一棵三色樹。
可愛的 alice覺得,乙個三色樹為均衡的,當且僅當,樹中不含有黑色結點
或者含有至多乙個白色節點。然而,給出的三色樹可能並不滿足這個性質。
所以,alice打算刪去若干條邊使得形成的森林中每棵樹都是均衡的,花費
的代價等於刪去的邊的權值之和。請你計算需要花費的代價最小是多少。
注意,輸入檔案包含多組測試資料。
input
第一行包含乙個正整數 t,表示有 t組測試資料。接下來依次是 t組測試數
據。每組測試資料的第一行包含乙個正整數 n。
第二行包含 n個 0、1、2之一的整數,依次表示點 1到點 n的顏色。其中,
0 表示黑色,1表示白色,2表示灰色。
接下來 n-1行,每行為三個整數ui、vi、c i,表示一條權值等於ci的邊(ui, vi)。
樹形dp
當至多取乙個的時候,我們需要計算出來不取的答案,然後減掉取min,即至多取乙個。
#include
#include
#include
#include
#define maxn 500010
using namespace std;
typedef long long ll;
ll dp[maxn][3];
int n;
struct edgeedge[maxn * 2];
int h[maxn], cnt;
void add(int u, int v, int d)
const ll inf = 1ll << 50;
int fa[maxn], c[maxn];
ll d[maxn];
int min(int a, int b, int c)
/* dp[u][2]//乙個白點。
dp[u][1]//無白點
dp[u][0]//無黑點
*/void dfs(int u)
if(c[u] == 0)
q = ret;
for(int i = h[u]; i; i = edge[i].next)
dp[u][2] = q;
dp[u][1] = ret;
dp[u][0] = inf; }
if(c[u] == 1)
dp[u][2] = ret2;
dp[u][1] = inf;
dp[u][0] = ret1; }
if(c[u] == 2)
q = ret;
for(int i = h[u]; i; i = edge[i].next)
dp[u][2] = q;
dp[u][1] = ret;
dp[u][0] = ret1; }}
int main()
d[1] = 0;dfs(1);
ll ans = min(dp[1][0], dp[1][1]);
ans = min(ans, dp[1][2]);
printf("%lld\n", ans);
} return 0;
}
bzoj3257 樹的難題
description 給出乙個無根樹。樹有n個點,邊有權值。每個點都有顏色,是黑色 白色 灰色這三種顏色之一,稱為一棵三色樹。可愛的 alice覺得,乙個三色樹為均衡的,當且僅當,樹中不含有黑色結點 或者含有至多乙個白色節點。然而,給出的三色樹可能並不滿足這個性質。所以,alice打算刪去若干條邊...
BZOJ3257 樹的難題
設 f x i j 表示以 x 為根的子樹,與 x 連通部分有 i 個黑點,j 個白點,不聯通部分都是均衡的最小代價。若 i 1 則視作 1 若 j 2 則視作 2 然後進行樹形dp即可,轉移的時候如果不要那棵子樹,那麼那棵子樹的狀態必須滿足 i j 2 時間複雜度 o n include defi...
1900 985的「樹」難題
time limit 1 sec memory limit 128 mb 985給你一棵 樹 以及它的根節點,要求你先判定它是否是一棵樹,其次他想知道每個節點的 太子 數目以及它的父親 root的話輸出自己 太子判定條件 一 若x是y的孩子節點,那麼x是y的 太子 二 若x是y的 太子 且y是z的 ...