時間限制: 1 sec 記憶體限制: 128 mb
hja有一棵n個點的樹,樹上每個點有點權,每條邊有顏色。
一條路徑的權值是這條路徑上所有點的點權和,一條合法的路徑需要滿足該路徑上任意相鄰的兩條邊顏色都不相同。
問這棵樹上所有合法路徑的權值和是多少。
第一行乙個數n。
接下來一行n個數代表每個點的權值。
接下來n−1行每行三個整數s,e,c,代表s到e之間有一條顏色為c的邊。
一行乙個整數代表答案。
樣例輸入
66 2 3 7 1 4
1 2 1
1 3 2
1 4 3
2 5 1
2 6 2
樣例輸出
134對於30%的資料,1≤n≤1000。
對於另外20%的資料,資料隨機。
對於另外20%的資料,是一條鏈。
對於100%的資料,1≤n
≤3×1
05,1
≤c≤1
09
1≤n≤3×10^5,1≤c≤10^9
1≤n≤3×
105,
1≤c≤
109。
樹形d pdp
dp+邊記憶化。
每次以i為端點dfs
dfsdf
s,同時記憶化從子樹中的一條邊開始的合法路徑的條數及總權值。
這樣每條邊(視為有向邊)最多訪問一次,總邊數為2∗n
−2
2*n-2
2∗n−
2,所以複雜度看似為o(n
)o(n)
o(n)
?最後,因為從每個點開始都dfs
dfsdf
s了一遍,所以結果要除2。
//#pragma gcc optimize(2)
//#pragma gcc optimize(3, "ofast", "inline")
#include
using namespace std;
typedef
long
long ll;
typedef
unsigned
long
long ull;
typedef pair<
int,
int> pii;
const
int n=
1e6+5;
const ll mod=
1e9+7;
const
double eps=
1e-5
;//const double pi=acos(-1);
#define ls p<<1
#define rs p<<1|1
int tot,nex[n]
,head[n]
,ver[n]
,col[n]
;ll a[n]
;void
add(
int u,
int v,
int w)
struct node;}
}vis[n]
;node dfs
(int u,
int fa,ll sum,
int e)
;for
(int i=head[u]
;i;i=nex[i]);
else;}
}return now;
}int
main()
for(
int i=
1;i<=n;i++
) ans+
=dfs
(i,0
,a[i],0
).sum;
cout<2
}
問題 B FZB(樹形DP 邊記憶化)
時間限制 1 sec 記憶體限制 128 mb hja有一棵n個點的樹,樹上每個點有點權,每條邊有顏色。一條路徑的權值是這條路徑上所有點的點權和,一條合法的路徑需要滿足該路徑上任意相鄰的兩條邊顏色都不相同。問這棵樹上所有合法路徑的權值和是多少。第一行乙個數n。接下來一行n個數代表每個點的權值。接下來...
訓練 9 13 訓練賽
a.hdu 6230 乙個合法的子串 s 3n 2 滿足條件即1 2n 1 為以n為回文中心的回文串,n 3n 2為以2n 1為中心的回文串。故我們可以通過尋找回文中心對,來判斷相應合法子串的個數。利用manacher求出每個位置的最長回文半徑,則若i,j滿足條件 i j 則應有 p i geqsl...
訓練賽 詠歎
安師大附中訓練題目 給定乙個1到n的排列a,對其進行氣泡排序 counter 0 while a不是公升序的 counter counter 1 for i 1 to n 1 if a i a i 1 then swap a i a i 1 endifend forend while那麼經過幾輪排序...