版权声明:学习,哪有那么多条条框框~ https://blog.csdn.net/Irish_Moonshine/article/details/89358250
ZOJ 3715 Kindergarten Election
题意:班级班长选举投票(每个人都不能投自己且一人一票),票数总值大于其他所有人的同学当选。现在有一个小朋友想成为班长,每个同学可以用x个糖果收买使其转投自己。
分析:直接猜想策略难以把握,并且无法验证正确性。所以不妨枚举这个小朋友最后以多少票当选班长,那么其他同学就肯定低于这个票数。即
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long int
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e3 + 10;
void init();
int cost[maxn]; int tcos[maxn];
struct node {
int id, val;
};
node vain[123][maxn];
int cmp(node a, node b) {
return a.val < b.val;
}
int van[123];
int len[maxn];
int n;
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
init();
for (int i = 2; i <= n; i++) {
scanf("%d", &van[i]);
}
for (int i = 2; i <= n; i++) {
scanf("%d", &cost[i]);
}
for (int i = 2; i <= n; i++) {
len[van[i]]++;
vain[van[i]][len[van[i]]].id = i;
vain[van[i]][len[van[i]]].val = cost[i];
}
for (int i = 1; i <= n; i++) {
if (len[i]) {
sort(vain[i] + 1, vain[i] + 1 + len[i], cmp);
}
}
int Min = INF;
for (int k = 2; k <= n; k++) {
int ans = 0;
int tmp = len[1];
int top = k-1;
for (int i = 2; i <= n; i++) tcos[i] = cost[i];
for (int i = 2; i <= n; i++) {
if (len[i] > top) {
for (int j = 1; j <= len[i] - top; j++) {
ans += vain[i][j].val; tmp++;
tcos[vain[i][j].id] = INF;
}
}
}
sort(tcos + 2, tcos + 1 + n);
for (int i = 2; i <= top + 1 - tmp + 1; i++) {
ans += tcos[i];
}
Min = min(ans, Min);
}
cout << Min << endl;
}
return 0;
}
void init() {
for (int i = 0; i <= n; i++) {
cost[i] = 0; van[i] = 0; len[i] = 0;
}
}