1. 程式人生 > >「NOI2011」道路修建

「NOI2011」道路修建

spa names namespace bsp lin 道路修建 getc void cto

傳送門:>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; }

「NOI2011」道路修建