————ACM————|POJ3253 Fence Repair (二叉堆 | 优先队列 | huffman树 )
本文出自:http://blog.csdn.net/svitter
题意:
给你几根木板,让你连接起来,每次连接花费为两根长度之和。连接所有的木板,最后最小的花费是多少。
【————ACM————|POJ3253 Fence Repair (二叉堆 | 优先队列 | huffman树 )】
输入输出分析:
略。
算法数据结构分析:
这个题目用贪心即可。即,每次的取两根最小的,花费最少,最后花费就最少。
本题目可以用二叉堆的最关键就在于二叉堆的定义:
大根堆:上面的比下面的大;
小根堆:上面的比下面的小;
通过一维数组最后一个添加或者删除,进行调整。
记于2014.08.01:
后来补充上优先队列的解法。
STL中的priority_queue就是使用的二叉堆实现的。
另外附上优先队列的使用方法:
struct cmp1
{
bool operator ()(int &a,int &b)
{
return a>b;
//最小值优先
}
};
struct cmp2
{
bool operator ()(int &a,int &b)
{
return aa.u;
//最小值优先
}
};
struct node2
{
int u;
bool operator < (const node2 &a) const
{
return uq1;
//采用默认优先级构造队列
priority_queue,cmp1>q2;
//最小值优先
priority_queue,cmp2>q3;
//最大值优先
priority_queue,greater >q4;
//注意“>>”会被认为错误,
//这是右移运算符,所以这里用空格号隔开,最小值优先
priority_queue,less >q5;
//最大值优先
priority_queueq6;
//自定义优先级
priority_queueq7;
1.一般堆解法:
时间消耗:
文章图片
#include
#include
#include
#include using namespace std;
__int64 a[20010];
int m, n;
void heap(int m)
{
int t;
while(m * 2 <= n)//有子堆
{
m = m * 2;
if(m < n && a[m] > a[m+1]) // 较大的子堆
{
m++;
}
if(a[m] < a[m / 2]) //
{
t = a[m];
a[m] = a[m/2];
a[m/2] = t;
}
else
break;
}
}void push_heap()
{
int i = n;
__int64 x = a[n];
while(i > 1 && a[i/2] > x)
{
a[i] = a[i/2];
i /= 2;
}
a[i] = x;
}void pop_heap()
{
__int64 x;
//swap top.root
x = a[1];
a[1] = a[n];
a[n] = x;
n--;
heap(1);
}void make_heap()
{
int i;
for(i = n / 2;
i > 0;
i --)//从n/2构建即可
{
heap(i);
}
}void ace()
{
int i;
__int64 cur0, cur1, cur, sum;
while(~scanf("%d", &n))
{
for(i = 1;
i <= n;
i++)
{
scanf("%I64d", &a[i]);
}
make_heap();
sum = 0;
while(n != 1)
{
pop_heap();
cur0 = a[n+1];
pop_heap();
cur1 = a[n+1];
cur = cur0 + cur1;
sum += cur;
a[++n] = cur;
push_heap();
}
printf("%I64d\n", sum);
}
}int main()
{
ace();
return 0;
}
2.类似冒泡解法
时间消耗:
文章图片
#include
#include
#include
#include using namespace std;
__int64 a[20010];
int m, n;
void ace()
{
int i;
__int64 cur0, cur1, cur, sum;
while(~scanf("%d", &n))
{
for(i = 1;
i <= n;
i++)
{
scanf("%I64d", &a[i]);
}
make_heap();
sum = 0;
while(n != 1)
{
pop_heap();
cur0 = a[n+1];
pop_heap();
cur1 = a[n+1];
cur = cur0 + cur1;
sum += cur;
a[++n] = cur;
push_heap();
}
printf("%I64d\n", sum);
}
}int main()
{
ace();
return 0;
}
3.模板STL解法
#include
#include
#include #define lln long long
using namespace std;
struct item
{
lln w;
bool operator < (const item &a)const
{
return w > a.w;
}
};
int n;
int main()
{
item t;
item t1, t2;
int i;
lln cost;
priority_queue - Queue;
while(~scanf("%d", &n))
{
for(i = 0;
i < n;
i++)
{
scanf("%lld", &t.w);
Queue.push(t);
}cost = 0;
while(!Queue.empty())
{
t1 = Queue.top();
Queue.pop();
if(Queue.empty())
break;
t2 = Queue.top();
Queue.pop();
t1.w += t2.w;
cost += t1.w;
if(Queue.empty())
break;
Queue.push(t1);
}
printf("%lld\n", cost);
}
return 0;
}
推荐阅读
- 急于表达——往往欲速则不达
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 2019-02-13——今天谈梦想()
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- Ⅴ爱阅读,亲子互动——打卡第178天
- 低头思故乡——只是因为睡不着
- 取名——兰
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术