原文链接:http://www.cnblogs.com/xiao_wu/archive/2010/06/01/1749416.html
BNUOJ 4112 奶牛大集会 http://acm.cist./contest/problem_show.php?pid=4212 这道题挺不错的,之前一次比赛中没过,看了解题报告也不知道啥意思,这几天看了树的知识,也就把这题想了出来。 1、将树看成以1为根的一棵有根树。 2、用一个sum[maxn]记录该节点以下的牛的个数。 3、用一个a[maxn]表示该节点为聚会地点时,奶牛们的不方便程度。 那么有: sum[ i ] = val[i] sum[ son(i) ]; a[ i ] = a[ son(i) ] sum[ son(i) ] * w; a[ i ] = (total - sum[ i ]) * w (a[ father(i) ] - a[ i ] - sum[v] * w); 其中val[i] 表示该点的牛数目,total 表示总的牛数量,w 表示 father(i) 到i点的距离。 这样,进行两次DFS,第一次DFS则要得到sum[]的值还有以这棵树来看时候的a[]值,这个时候a[]值仅为a[ son(i) ] sum[ son(i) ] * w,不算包括父亲在内的另一部分子树的不满意度,第二次DFS则要计算a[],需要两次DFS的原因是,必须要用一个节点的不满意度已经求出,才能求出这个点以下的节点的不满意度。 题目超int ,直接用long long 表示了。 ![]() ![]() 2 #include <iostream> 3 using namespace std; 4 5 const int maxn = 1000000 1; 6 typedef long long LL; 7 8 LL val[maxn], n, visit[maxn], sum[maxn], a[maxn], total, e_num; 9 struct node 10 { 11 LL v, w; 12 node* next; 13 } *adj[maxn], edge[maxn]; 14 15 void add_edge(LL u, LL v, LL w) 16 { 17 node* ptr = &edge[ e_num ]; 18 ptr -> v = v; 19 ptr -> w = w; 20 ptr -> next = adj[u]; 21 adj[u] = ptr; 22 } 23 24 void DFS(LL u) 25 { 26 visit[u] = 1; 27 for(node* ptr = adj[u]; ptr; ptr = ptr -> next) 28 { 29 LL v = ptr -> v; 30 LL w = ptr -> w; 31 if(visit[v]) 32 continue; 33 DFS(v); 34 sum[u] = sum[v]; 35 a[u] = (a[v] sum[v] * w); 36 } 37 sum[u] = val[u]; 38 } 39 40 void GET(LL u) 41 { 42 visit[u] = 1; 43 for(node* ptr = adj[u]; ptr; ptr = ptr -> next) 44 { 45 LL v = ptr -> v; 46 LL w = ptr -> w; 47 if(visit[v]) 48 continue; 49 a[v] = (total - sum[v]) * w (a[u] - a[v] - sum[v] * w); 50 GET(v); 51 } 52 } 53 54 void solve() 55 { 56 DFS(1); 57 memset(visit , 0 , sizeof(visit)); 58 GET(1); 59 LL mn = a[1]; 60 for(LL i=1; i <= n; i ) 61 { 62 mn = min(mn , a[i]); 63 } 64 printf("%lld\n", mn); 65 } 66 67 int main() 68 { 69 scanf("%lld", &n); 70 total = e_num = 0; 71 for(LL i=1; i <= n; i ) 72 { 73 scanf("%lld", &val[i]); 74 total = val[i]; 75 } 76 LL u , v , w; 77 for(LL i=1; i <= n - 1; i ) 78 { 79 scanf("%lld %lld %lld", &u, &v, &w); 80 add_edge(u, v, w); 81 add_edge(v, u, w); 82 } 83 solve(); 84 return 0; 85 } 86
转载于:https://www.cnblogs.com/xiao_wu/archive/2010/06/01/1749416.html 来源:https://www./content-4-341151.html |
|