poj2054 Color a Tree Problem Solution Report

Keywords: PHP

Topic portal

[General idea of the title]

A tree with $n $nodes, each of which has a weight of $A_i$. Now the tree's nodes will be dyed all, the rule is: the root node $R $can be dyed at any time; for other nodes, its father node must have been dyed before it is dyed. The cost of each dyeing is $T*A_i$, where $T$represents the current number of dyes. Seek the minimum total cost of dyeing the tree.

[Idea analysis]

It is easy to have a wrong algorithm for this problem, that is, "each step chooses the dyeing with the greatest weight in the point that can be dyed". We can obviously construct a counter example: a node with small weight has many nodes with huge weight, while another node with large weight has no child nodes. But we can extract a correct property from it: the point with the largest weight except the root node in the tree will be dyed immediately after its parent node is dyed. So we can confirm that the dyeing operation of the point with the largest weight in the tree and its parent node is continuous, and we can "merge" the two points. The weights of the merged new points are set as the average of the weights of the two points.

So the greedy strategy is to merge the point with the largest weight with its father node every time, until the whole tree is merged into a point, and then calculate the answer in order.

[Code implementation]

 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         go(i,1,n) scanf("%d",&a[i]),num[i]=1;
14         //num Record the number of original nodes contained at this point
15         go(i,1,n-1){
16             int x,y;
17             scanf("%d%d",&x,&y);
18             fa[y]=x;
19         }
20         go(i,1,n-1){
21             double maxn=0;int now;//now Record the nodes to be merged
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]];//merge
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 stamp here

Posted by btrsrinivasarao on Wed, 31 Jul 2019 00:50:46 -0700