1 /*
POJ-2054 color a tree
3 *
4 * greedy problem!
5 *
6 * Idea 1:
7 * http://hi.baidu.com/cheezer94/blog/item/d98eca065202a2f237d122da.html
8 * idea 2:
9 * http://www.cnblogs.com/X-Kly/archive/2011/11/02/POJ2054.html
10 * code:
11 * http://xinbaolianmeng.com/showshouye.aspx? Type = 6 & id = 110
12 *
13 * To put it simply:
14 * Find the "set" with the largest weight value each time and merge it with the "parent set". The weight is the average of the vertex weights in the two sets.
15 * until only one set is left
16 *
17 *
18 * the following sample code is the same. You can view its comments.
19 *
20 *
21 */
22
23
24 # include <cstdio>
25 using namespace STD;
26
27 const int maxn = 1000 + 5;
28
29 int N, R;
30 int C [maxn], Fa [maxn];
31 int pre [maxn], next [maxn], sum [maxn], num [maxn];
32 bool vis [maxn];
33
34 int find_max (){
35 double max =-1;
36 int maxnum =-1;
37 For (INT I = 1; I <= N; I ++ ){
38 If (! Vis [I] & (sum [I] * 1.0/num [I])> MAX ){
39 max = (sum [I] * 1.0/num [I]);
40 maxnum = I;
41}
42}
43 return maxnum;
44}
45
46
47 void unionfa (int x ){
48 int faset;
49 for (faset = Fa [X]; Pre [faset]! =-1; faset = pre [faset]);
50 sum [faset] + = sum [x];
51 num [faset] + = num [x];
52 for (faset = Fa [X]; next [faset]! =-1; faset = next [faset]);
53 next [faset] = X;
54 pre [x] = faset;
55
56 vis [x] = 1;
57}
58
59 int main (){
60 while (scanf ("% d", & N, & R )){
61 If (n = 0) return 0;
62
63 for (INT I = 1; I <= N; I ++) {// note that it starts from 1 !! (Because the numbers of input roots and edges start from 1)
64 scanf ("% d", & C [I]);
65 sum [I] = C [I];
66 num [I] = 1;
67 pre [I] = next [I] =-1;
68 vis [I] = false;
69}
70
71 int U, V;
72 for (INT I = 1; I <n; I ++ ){
73 scanf ("% d", & U, & V );
74 Fa [v] = u;
75}
76
77 int D;
78 vis [R] = 1;
79 while (1 ){
80 d = find_max ();
81 If (D =-1) break;
82 unionfa (d );
83}
84
85 int ans = 0, T = 1;
86 for (INT I = r; I! =-1; I = next [I]) {
87 ans + = T * C [I];
88 t ++;
89}
90 printf ("% d \ n", ANS );
91}
92
93
94 return 0;
95}
96
97/* = ================================
98
99 # include <iostream>
100 # include <cstdio>
101 using namespace STD;
102 const int max_n = 1010;
103 int pre [max_n]; // pre [I] indicates the previous element of the current set (including I ).
104 int next [max_n]; // next [I] indicates the next element of the current set (including I ).
105 int C [max_n];
106 int num [max_n]; // num [I] indicates the number of elements in the current set (including I)
107 int visit [max_n];
108 int sum [max_n]; // the elements of the current set and
109 int father [max_n]; // father [I] indicates the parent element of I.
110 int N, R;
111 int find_max () // find the set with the largest current weight. The merged vertex is treated as a set, that is, a vertex.
112 {
113 double max = 0;
114 int bH =-1;
115 for (INT I = 1; I <= N; I ++)
116 {
117 If (max <(sum [I] * 1.0)/num [I] & visit [I] = 0)
118 {
119 max = (sum [I] * 1.0)/num [I];
120 bH = I;
121}
122}
123 return BH;
124}
125 void uni (int x) // Union
126 {
127 int I;
128 for (I = Father [X]; Pre [I]! =-1; I = pre [I]); // locate the set where the parent element is located
129 sum [I] + = sum [x];
130 num [I] + = num [x];
131 for (I = Father [X]; next [I]! =-1; I = next [I]); // locate the base element of the set where the parent element is located
132 next [I] = X;
133 pre [x] = I;
134 visit [x] = 1;
135}
136 int main ()
137 {
138
139 while (scanf ("% d", & N, & R), N & R)
140 {
141 for (INT I = 1; I <= N; I ++)
142 {
143 scanf ("% d", & C [I]);
144 sum [I] = C [I];
145 visit [I] = 0;
146 pre [I] = next [I] =-1;
147 num [I] = 1;
148}
149 for (INT I = 1; I <n; I ++)
150 {
151 int A, B;
152 scanf ("% d", & A, & B );
153 father [B] =;
154}
155
156 int D;
157 visit [R] = 1;
158 while (1)
159 {
160 d = find_max ();
161 If (D =-1) break;
162 uni (d );
163}
164 int ans = 0, tjq = 1;
165 for (INT I = r; I! =-1; I = next [I])
166 {
167 ans + = tjq * C [I];
168 tjq ++;
169}
170 printf ("% d \ n", ANS );
171}
172
173 return 0;
174}
175
176 */