http://www.lydsy.com/JudgeOnline/problem.php?id=2435
noi 你为什么那么diao, 这种世纪水题刷一道少一道啊。。。 我原来还以为是两边的联通块大小按已经连接上的点来算,然后发现是按照最后的联通块来算的(' ' ) 直接每个点 abs(n - 2 * size[x]) * dis(边权)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1000100; struct edge { int t, d; edge* next; }e[maxn * 2], *head[maxn]; int ne = 0; int n, m; void addedge(int f, int t, int d) { e[ne].t = t, e[ne].d = d, e[ne].next = head[f], head[f] = e + ne ++; } int sta[maxn], top = 0, size[maxn], dis[maxn]; void dfs(int x, int fa) { sta[++ top] = x; size[x] = 1; for(edge* p = head[x]; p; p = p-> next) { if(p-> t != fa) dis[p-> t] = p-> d, dfs(p-> t, x), size[x] += size[p-> t]; } } int int_get() { int x = 0; char c = (char)getchar(); bool f =0 ; while(!isdigit(c)) { if(c == '-') f = 1; c = (char)getchar(); } while(isdigit(c)) { x = x * 10 + (int)(c - '0'); c = (char)getchar(); } if(f) x = -x; return x; } void read() { n = int_get(); for(int i = 1; i < n; ++ i) { int u, v, w; u = int_get(), v = int_get(), w = int_get(); addedge(u, v, w), addedge(v, u, w); } } long long ans = 0; void sov() { dfs(1, 0); for(int i = top; i >= 2; -- i) { ans += (long long)(abs(n - 2 * size[sta[i]])) * (long long)dis[sta[i]]; } printf("%lld\n", ans); } int main() { //freopen("test.in", "r", stdin); read(), sov(); return 0; }