这道题题意不解释,《算法竞赛入门经典训练指南》里都有翻译,不知道的去看看吧。
哦,对了,我刚刚说要写替罪羊树的,后来又想了想,把之前的这个代码贴了上来,大家可以看时间嘛。(如果你不知道替罪羊树是什么,看这个网址————————————————–,当然,我刚刚说了,说了什么?这里也有一个网址的http://blog.csdn.net/ljf_cnyali/article/details/52588662)。
本来博主写的堆,是不是写的很丑?
/*************************************************************************
> File Name: \LJF\UVa\UVa_11136.cpp
> Author: ljf_cnyali
> Mail: 2724424647@qq.com
> Last modifiedz: 2016-08-27 14:59
> Description: This is a large group of God's program information.
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
#define REP(i, a, b) for(long long i = (a), _end_ = (b);i <= _end_; ++i)
const long long maxn = 10010000;
long long max_heap[maxn], min_heap[maxn];
long long max_len, min_len;
void min_insert(long long x) {
min_heap[++min_len] = x;
long long k = min_len, t;
while(k > 1 && min_heap[k] < min_heap[k / 2]) {
t = min_heap[k];
min_heap[k] = min_heap[k / 2];
min_heap[k / 2] = t;
k /= 2;
}
}
void max_insert(long long x) {
max_heap[++max_len] = x;
long long k = max_len, t;
while(k > 1 && max_heap[k] > max_heap[k / 2]) {
t = max_heap[k];
max_heap[k] = max_heap[k / 2];
max_heap[k / 2] = t;
k /= 2;
}
}
int main() {
long long n, t, m, f, k;
while(1) {
scanf("%lld", &f);
memset(max_heap, 0, sizeof(max_heap));
memset(min_heap, 0, sizeof(min_heap));
max_len = 0;
min_len = 0;
if(f == 0)
return 0;
long long ans = 0;
REP(l, 1, f) {
scanf("%lld", &n);
REP(i, 1, n){
scanf("%lld", &k);
max_insert(k);
min_insert(k);
}
ans += max_heap[1] - min_heap[1];
min_heap[1] = min_heap[min_len--];
k = 1;
while((2 * k <= min_len && min_heap[k] > min_heap[2 * k]) || (2 * k <= min_len && min_heap[k] > min_heap[2 * k + 1])) {
m = 2 * k;
if(m + 1 <= min_len && min_heap[m] > min_heap[m + 1])
m++;
t = min_heap[k];
min_heap[k] = min_heap[m];
min_heap[m] = t;
k = m;
}
max_heap[1] = max_heap[max_len--];
k = 1;
while((2 * k <= max_len && max_heap[k] < max_heap[2 * k]) || (2 * k + 1 <= max_len && max_heap[k] < max_heap[2 * k + 1])) {
m = 2 * k;
if(m + 1 <= max_len && max_heap[m] < max_heap[m + 1])
m++;
t = max_heap[k];
max_heap[k] = max_heap[m];
max_heap[m] = t;
k = m;
}
}
printf("%lld\n", ans);
}
return 0;
}
WA了好久,都是Wrong answer,自己都觉得烦了。本来想写堆练下手,最后还是被迫选择了STL。
STL的代码在此:
/*************************************************************************
> File Name: \LJF\UVa\UVa_11136.cpp
> Author: ljf_cnyali
> Mail: 2724424647@qq.com
> Last modifiedz: 2016-08-27 16:59
> Description: This is a large group of God's program information.
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
#define REP(i, a, b) for(long long i = (a), _end_ = (b);i <= _end_; ++i)
multiset<long long> q;
int main() {
long long n, t, m, f, k;
while(1) {
q.clear();
scanf("%lld", &f);
if(f == 0)
return 0;
long long ans = 0;
REP(l, 1, f) {
scanf("%lld", &n);
REP(i, 1, n){
scanf("%lld", &k);
q.insert(k);
}
auto s = q.begin(), e = q.end(); --e;
ans += *e - *s;
q.erase(e);
q.erase(q.begin());
}
printf("%lld\n", ans);
}
return 0;
}