Question:
Long long ans = 0;
For (INT I = 1; I <= N; I ++)
For (Int J = I + 1; j <= N; j ++)
Ans + = f (I, j );
F (I, j) indicates all vertices and rights in the I-to-J Path.
F (I, j) = 0 if two adjacent edges have the same weight on the I-> J Path
Q: The value of ans.
I'm also drunk when the int multiplication is exploding...
Ideas:
Different from the statistical edge method on the Internet, the number of occurrences of the statistical point is calculated here.
When we calculate the number of times each vertex I appears, the answer is the number of times I exists * I point privilege => DP [I] * A [I]
I has four types of paths: start and end.
1. descendant of I-> descendant of I
2. descendant of I-> I
3. I to (not the descendant of I (that is, the ancestor node of I, the descendant of the sibling node and the sibling node)
4. descendant of I-> descendant of non-I
Therefore, first calculate the case of 1 and 2, and use dp1 [I] to record
Use dp2 [I] to record 3 and 4 cases
The answer is for (INT I = 1; I <= N; I ++) ans + = A [I] * (dp1 [I] + dp2 [I]);
Siz [u] indicates the number of valid nodes in the subtree rooted in U. If U-> V (COL = 1) & V-> K (COL = 1 ), then, the subtree with K as the root is not a valid node.
(V is the son of U, and K is the son of V)
MP [u] [col] indicates the number of nodes connected by the edges with the color Col in the valid node.
# Include <map> using namespace STD; # define n 300100 struct edge {int to, Col, NEX;} edge [n <1]; int head [N], edgenum; void Init () {memset (Head,-1, sizeof head); edgenum = 0;} void add (int u, int V, int col) {edge e = {v, col, head [u]}; edge [edgenum] = E; head [u] = edgenum ++;} typedef long ll; template <class T> inline bool RD (T & RET) {char C; int SGN; If (C = getchar (), c = EOF) return 0; while (C! = '-' & (C <'0' | C> '9') c = getchar (); SGN = (C = '-')? -1:1; ret = (C = '-')? 0 :( C-'0'); While (C = getchar (), c> = '0' & C <= '9 ') ret = RET * 10 + (c-'0'); RET * = SGN; return 1;} template <class T> inline void Pt (t x) {If (x> 9) Pt (X/10); putchar (X % 10 + '0');} int N, K; ll dp1 [N], dp2 [N], a [n]; int siz [N]; Map <int, int> MP [N], MP2 [N]; // MP [u] [col] indicates the number of valid points of the edge color = Col under the U subtree void dfs1 (int u, int FA) {siz [u] = 0; dp1 [u] = 0; For (INT I = head [u]; ~ I; I = edge [I]. NEX) {int v = edge [I]. to; If (V = FA) continue; dfs1 (v, U); MP [u] [edge [I]. col] + = siz [v]-MP [v] [edge [I]. col]; siz [u] + = siz [v]-MP [v] [edge [I]. col];} ll Dou = 0; For (INT I = head [u]; ~ I; I = edge [I]. NEX) {int v = edge [I]. to; If (V = FA) continue; Dou + = (LL) (siz [v]-MP [v] [edge [I]. col]) * (LL) (siz [u]-MP [u] [edge [I]. col]); dp1 [u] + = siz [v]-MP [v] [edge [I]. col];} dp1 [u] + = Dou> 1; siz [u] ++;} void dfs2 (int u, int OK, int Col, int FA) {dp2 [u] = (LL) (siz [u]-MP [u] [col]) * (LL) OK; For (INT I = head [u]; ~ I; I = edge [I]. NEX) {int v = edge [I]. To; If (V = FA) continue; If (u! = Fa & edge [I]. col = col) dfs2 (v, siz [u]-MP [u] [edge [I]. col], edge [I]. col, U); else dfs2 (v, OK + siz [u]-MP [u] [edge [I]. col], edge [I]. col, u) ;}void solve () {Init (); For (INT I = 1; I <= N; I ++) RD (A [I]), MP [I]. clear (), MP2 [I]. clear (); For (INT I = 1, U, V, D; I <n; I ++) {RD (U); rd (v ); rd (d); add (u, v, d); add (v, U, d);} dfs1 (1, 1); dfs2 (1, 0,-1, 1) ;}int main () {While (RD (N) {solve (); LL ans = 0; For (INT I = 1; I <= N; I ++) ans + = A [I] * (dp1 [I] + dp2 [I]); Pt (ANS); putchar ('\ n ');} return 0 ;} /* 41 10 100 10001 2 12 3 13 4 151 10 100 1000 100001 2 12 3 13 4 12 5 2111 2 3 5 6 7 8 9 111 1231 2 11 3 22 4 32 5 13 6 33 7 35 8 15 9 10 111 8 2141 2 3 4 5 6 7 8 9 111 123 235 10001 2 11 3 22 4 32 5 13 6 33 7 35 8 15 9 28 10 111 8 212 11 28 13 18 14 2101 1 1 1 1 1 1 11 11 2 11 11 10 22 3 52 6 43 4 13 5 87 8 27 9 1141 2 5 10 20 30 70 80 100 1000 2000 5000 100000 2 21 3 11 4 12 5 22 8 33 9 33 6 24 7 14 10 33 11 36 12 10000001 1 213 3 */
HDU 4303 hourai jeweled tree DP all path points and dfs2 requests