poj 3253 Fence Repair

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 7947 Accepted: 2530

     本题其实很简单,就是简单的赫夫曼,因为每次将他们分开两半的时候都要按照长度收费,也就是说第一次被分开的只收费了一次,第二次被分开的收费了二次(因为前面已经收费了一次)......第n次分开的要收费n次。就是求如何合理的安排是的总费用最小,这是典型的最优生成树的问题,根据所给的数据作为权值生成赫夫曼树,然后再计算一下总的权值即可。

注意:本题的记过可能很大,用Int型估计不能过,建议__int64

代码:

 

  
    
1 #include < stdio.h >
2 #include < queue >
3   using namespace std;
4
5 typedef struct T
6 {
7 int data;
8 struct T * Lchild, * Rchild;
9 } * Tree;
10 typedef struct node
11 {
12 int data;
13 int h;
14 Tree t;
15 bool operator < ( const node & a) const
16 {
17 if (a.data != data)
18 return a.data < data;
19 else
20 return a.h < h;
21 }
22 }NODE;
23 NODE cur,cur1,cur2;__int64 sum;
24 priority_queue < NODE > qu;
25   void createtree()
26 {
27 cur1 = qu.top();
28 qu.pop();
29 if (qu.empty ())
30 return ;
31 cur2 = qu.top();
32 qu.pop();
33 cur.data = cur1.data + cur2.data;
34 cur.h = 1 ;
35 cur.t = (Tree)malloc( sizeof (T));
36 cur.t -> Lchild = cur1.t;
37 cur.t -> Rchild = cur2.t;
38 cur.t -> data = 0 ;
39 qu.push(cur);
40 createtree();
41 }
42 void visit(Tree root, int floor)
43 {
44 if (root -> data != 0 )
45 sum += root -> data * floor;
46 if (root -> Lchild != NULL)
47 visit(root -> Lchild,floor + 1 );
48 if (root -> Rchild != NULL)
49 visit(root -> Rchild,floor + 1 );
50 }
51 int main()
52 {
53 int n,a;
54 scanf( " %d " , & n);
55 sum = 0 ;
56 while (n -- )
57 {
58 scanf( " %d " , & a);
59 cur.data = a;
60 cur.h = 0 ;
61 cur.t = (Tree)malloc( sizeof (T));
62 cur.t -> data = a;
63 cur.t -> Lchild = NULL;
64 cur.t -> Rchild = NULL;
65 qu.push(cur);
66 }
67 if (qu.size() == 1 )
68 {
69 printf( " 0\n " );
70 }
71 else
72 {
73 createtree();
74 visit(cur1.t, 0 );
75 printf( " %I64d\n " ,sum);
76 }
77 return 0 ;
78 }
79
80

 

你可能感兴趣的:(AIR)