传送门:>HERE<
题意:给出一棵树(带权),答案为每条边的权值乘以两边节点数之差的和。
解题思路:
Dfs就好了,维护一下子树大小。
这题做得真是心惊胆战……不知道为什么70分WA了许多次,最后把cmath里的abs函数改成algorithm里的或是手打的就AC了…………
教训:永远手打Abs,不差这三四行。
Code
/*By QiXingzhi*/ #include <cstdio> #include <queue> #define r read() #define Max(a,b) (((a)>(b)) ? (a) : (b)) #define Min(a,b) (((a)<(b)) ? (a) : (b)) using namespace std; typedef long long ll; #define int ll const int N = 2000010; const int INF = 1061109567; inline int read(){ int x = 0; int w = 1; register int c = getchar(); while(c ^ '-' && (c < '0' || c > '9')) c = getchar(); if(c == '-') w = -1, c = getchar(); while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar(); return x * w; } struct Edge{ int to, cost; }; int n,x,y,z,ans; vector <Edge> G[N]; int son[N]; inline void AddEdge(int u, int v, int w){ Edge e; e.to = v, e.cost = w; G[u].push_back(e); } inline int ABS(int x){ if(x < 0) return -x; return x; } void Dfs(int x, int father){ son[x] = 1; int sz = G[x].size(); for(int i = 0; i < sz; ++i){ int v = G[x][i].to; if(v == father) continue; Dfs(v, x); son[x] += son[v]; ans += G[x][i].cost * ABS(son[v] - (n-son[v])); } } main(){ //freopen(".in","r",stdin); n = r; for(int i = 1; i < n; ++i){ x = r, y = r, z = r; AddEdge(x, y, z); AddEdge(y, x, z); } Dfs(1, 0); printf("%lld", ans); return 0; }