POJ2054Color a Tree(贪心)

女爷i 2021-09-15 23:08 368阅读 0赞

Color a Tree
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 8297 Accepted: 2861
Description

Bob is very interested in the data structure of a tree. A tree is a directed graph in which a special node is singled out, called the “root” of the tree, and there is a unique path from the root to each of the other nodes.

Bob intends to color all the nodes of a tree with a pen. A tree has N nodes, these nodes are numbered 1, 2, …, N. Suppose coloring a node takes 1 unit of time, and after finishing coloring one node, he is allowed to color another. Additionally, he is allowed to color a node only when its father node has been colored. Obviously, Bob is only allowed to color the root in the first try.

Each node has a “coloring cost factor”, Ci. The coloring cost of each node depends both on Ci and the time at which Bob finishes the coloring of this node. At the beginning, the time is set to 0. If the finishing time of coloring node i is Fi, then the coloring cost of node i is Ci * Fi.

For example, a tree with five nodes is shown in Figure-1. The coloring cost factors of each node are 1, 2, 1, 2 and 4. Bob can color the tree in the order 1, 3, 5, 2, 4, with the minimum total coloring cost of 33.

Given a tree and the coloring cost factor of each node, please help Bob to find the minimum possible total coloring cost for coloring all the nodes.
Input

The input consists of several test cases. The first line of each case contains two integers N and R (1 <= N <= 1000, 1 <= R <= N), where N is the number of nodes in the tree and R is the node number of the root node. The second line contains N integers, the i-th of which is Ci (1 <= Ci <= 500), the coloring cost factor of node i. Each of the next N-1 lines contains two space-separated node numbers V1 and V2, which are the endpoints of an edge in the tree, denoting that V1 is the father node of V2. No edge will be listed twice, and all edges will be listed.

A test case of N = 0 and R = 0 indicates the end of input, and should not be processed.
Output

For each test case, output a line containing the minimum total coloring cost required for Bob to color all the nodes.
Sample Input

5 1
1 2 1 2 4
1 2
1 3
2 4
3 5
0 0
Sample Output

33
Source

Beijing 2004

个人感觉这题很神仙
首先我们可以很容易找到一个错误的贪心算法(每一步在可以被染色的点里选权值最大的染色),然而我们很容易构造一棵树,让一个权值很小的节点下面有很多权值很大的节点,另一个权值较大的点却没有子节点。
但是我们可以从中得到一个正确的性质:树中除根节点外最大的点,一定会在它的父节点被染色后立即染色。
我们可以想到这两个操作是连续的,然后我们可以把这两个节点合并,合并得到的权值为这两个点的权值的平均值。
接下来是很神仙的证明

假设有权值为x,y,z的三个点,x和y的操作是连续的,那么有两个可能的方案
1.先染x,y
—————w=x+2y+3z
2.先染z
—————w=z+2x+3y
然后我们比较w的大小,给两边加上(z-y)除以2
1.————w=(x+y)/2+2*z;
2.————w=z+2*((x+y)/2);
这就变成了权值为(x+y)/2和z的两个点的次序!!!!!!

然后我们可以想到一个算法,记录每个点是由多少个点合并来的,这个点的权值就等于原始权值和除以原始点数
然后我们不断的合并,最后一棵树就合并成了一个点,值得注意的是我们要保存顺序,最后按照顺序计算它的总代价

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <string>
  7. #include <vector>
  8. #include <list>
  9. #include <map>
  10. #include <queue>
  11. #include <stack>
  12. #include <bitset>
  13. #include <algorithm>
  14. #include <assert.h>
  15. using namespace std;
  16. #define rep(i,a,n) for (int i=a;i<n;i++)
  17. #define per(i,a,n) for (int i=n-1;i>=a;i--)
  18. #define pb push_back
  19. #define mp make_pair
  20. #define all(x) (x).begin(),(x).end()
  21. #define fi first
  22. #define se second
  23. #define SZ(x) ((int)(x).size())
  24. typedef vector<int> VI;
  25. typedef long long ll;
  26. typedef pair<int,int> PII;
  27. const ll mod=1000000007;
  28. ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){
  29. if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
  30. ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
  31. //head
  32. const int maxn = 1100;
  33. int n,r;
  34. struct node
  35. {
  36. int t,p,c;
  37. double w;
  38. } num[maxn];
  39. int find()
  40. {
  41. double ma = 0;
  42. int res;
  43. rep(i,1,n+1)
  44. {
  45. if(i != r&&num[i].w > ma)
  46. {
  47. ma = num[i].w;
  48. res = i;
  49. }
  50. }
  51. return res;
  52. }
  53. int main()
  54. {
  55. while(scanf("%d%d",&n,&r)!=EOF&&(n!=0||r!=0))
  56. {
  57. int ans = 0;
  58. rep(i,1,n+1)
  59. {
  60. scanf("%d",&num[i].c);
  61. num [i].w = num[i].c;
  62. num[i].t = 1;
  63. ans += num[i].c;
  64. }
  65. rep(i,1,n)
  66. {
  67. int a,b;
  68. scanf("%d%d",&a,&b);
  69. num[b].p = a;
  70. }
  71. rep(i,1,n)
  72. {
  73. int pos = find();
  74. num[pos].w = 0;
  75. int f = num[pos].p;
  76. ans += num[pos].c*num[f].t;
  77. rep(j,1,n+1)
  78. if(num[j].p == pos)
  79. {
  80. num[j].p = f;
  81. }
  82. num[f].c += num[pos].c;
  83. num[f].t += num[pos].t;
  84. num[f].w = double(num[f].c)/num[f].t;
  85. }
  86. printf("%d\n",ans);
  87. }
  88. return 0;
  89. }

发表评论

表情:
评论列表 (有 0 条评论,368人围观)

还没有评论,来说两句吧...

相关阅读

    相关 POJ--2513 Colored Sticks

    这一题本能的想法就是把所有的单词都读入,统计一下每种单词的个数,判断是否构成欧拉通路,判断图是否连通。 可是可是题目给的不是数字而是单词,着我该怎么办??? 数字

    相关 HDU 6241 Color a Tree

    题意:给你一棵树,然后让你对树上的节点进行黑白染色。然后染色有一些要求,对于A类要求,要求在x的子树中,至少有y个节点被染成了黑色;对于B类要求,要求在树的所有节点除了x以及

    相关 poj2054 Color a Tree

    神题。这题是巨毒瘤... 自己写真可谓是: 排空驭气奔如电,上天入地求之遍 上穷碧落下黄泉,两处茫茫皆不见 由于我们知道:不是树形时,不停选值最大的节点可以得到最小代价