「NOI2011」道路修建
阿新 • • 發佈:2018-07-20
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() #defineMax(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]; inlinevoid 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」道路修建