poj2054 Color a Tree explanations report

Topic Portal

[Title] effect

 An n-$ $ trees of nodes, each node $ I $ has a weight $ A_i $. Now put this tree all the nodes stained rules: root $ R $ can always be stained; for other nodes before being dyed its parent node must have been infected with the color. Every time the cost of dyeing is $ T * A_i $, where $ T $ represents the current many times stained. Seeking a minimum total cost of this tree staining.

[Analysis] ideas

This problem is easy to have a faulty algorithm is "every step of the largest dyeing can be dyed at a point where the value of the right to choose," we obviously can construct a counter-example - a small weight nodes below node huge lot of weight another larger weight node has no children. However, we can extract a proper nature: tree except root outside the maximum weight point, will stain immediately after its parent stained. So we can be sure that the maximum weight of the tree point and its parent dyeing operation is carried out continuously, we can put two points "merged." The right to a new point of consolidation resulting value to the average weights of these two points.

So greedy strategy is to select the maximum weight of each point and its parent node merger, until finally the whole tree merge into a point, and then in order to calculate the answer.

【Code】

 1 #include<cstdio>
 2 #include<iostream>
 3 #define rg register
 4 #define go(i,a,b) for(rg int i=a;i<=b;i++)
 5 #define ll long long
 6 using namespace std;
 7 const int N=1002;
 8 int n,root,fa[N],a[N],num[N];
 9 ll ans=0;
10 int main(){
11     scanf("%d%d",&n,&root);
12     while(n&&root){
13 is          Go (I, . 1 , n-) Scanf ( " % D " , A & [I]), num [I] = . 1 ;
 14          // Number of points included in the original recording num node 
15          Go (I, . 1 , n- - . 1 ) {
 16              int X, Y;
 . 17              Scanf ( " % D% D " , & X, & Y);
 18 is              FA [Y] = X;
 . 19          }
 20 is          Go (I, . 1 , N- . 1 ) {
 21 is              Double = MAXN 0 ; int now; //now记录要合并的节点
22             go(i,1,n)
23                 if(i!=root&&1.0*a[i]/num[i]>=maxn)maxn=1.0*a[i]/num[i],now=i;
24             go(i,1,n)
25                 if(fa[i]==now) fa[i]=fa[now];
26             ans+=a[now]*num[fa[now]];//合并
27             num[fa[now]]+=num[now];
28             a[fa[now]]+=a[now];a[now]=0;
29         }
30         ans+=a[root];
31         printf("%lld\n",ans);
32         scanf("%d%d",&n,&root);ans=0;
33     }
34     return 0;
35 }
Code poke here

Guess you like

Origin www.cnblogs.com/THWZF/p/11257688.html