您的位置:首页 > 其它

ZOJ-3715-Kindergarten Election

2017-02-13 17:12 323 查看
在学期开始的幼儿园,n个小孩(1到n)在课堂上需要选择他们的新领导。
第一个孩子会投票给他最好的朋友fi(其中1≤fi≤n,这太可惜了,自己投票,所以fi≠i)。 

获得最多票数的孩子将是领袖。 如果有一个以上的孩子获得最多的票数,在新学期将有多个领导人。

小谢尔顿(下标为1)想成为唯一的领导者。 (这意味着他得到的票数应该严格大于任何其他。)

如果他给ci糖果给第i个孩子,第i个孩子会认为谢尔顿作为新的最好的朋友,当然投票谢尔顿。

请帮助谢尔顿成为唯一的领导者,最低的糖果成本。 顺便说一下,谢尔顿应该投票支持自己想要的任何一个人。

枚举获胜所需要的票数,从其他超过该票数的中买票(当然从便宜的开始买),如果买完后还不够枚举的票数就买其他没有买过的票.

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <queue>
#include <vector>
#include <math.h>
#include <stack>
#include <map>
#define rtl rt<<1
#define rtr rt<<1|1
typedef long long LL;
using namespace std;
const int MAX = 15000+10;
const double eps = 1e-10;
const double PI = acos(-1.0);
int t, n, f[MAX], c[MAX], ans, ant, num, num0;
bool vis[MAX];
struct node
{
int c, id;
};
bool operator < (node a, node b)
{
if(a.c!=b.c)return a.c>b.c;
return a.id<b.id;
}
priority_queue<node>que[MAX], que2[MAX], qq, qqq;
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = 1; i<=n; ++i)
while(!que[i].empty())que[i].pop();
while(!qq.empty())qq.pop();
for(int i = 2; i<=n; ++i)
cin>>f[i];
num0 = 0;
for(int i = 2; i<=n; ++i)
{
node ver;
scanf("%d", &ver.c);
ver.id = i;
if(f[i]!=1)
{
que[f[i]].push(ver);
qq.push(ver);
}
else num0++;
}
ans = 0x7fffffff;
for(int i = max(2, (int)que[1].size()); i<=n; ++i)
{
num = num0;
ant = 0;
memset(vis, 0, sizeof(vis));
for(int j = 2; j<=n; ++j)
{
que2[j] = que[j];
while((int)que2[j].size()>i-1)
{
node ver = que2[j].top();
que2[j].pop();
ant+=ver.c;
vis[ver.id] = 1;
num++;
}
if(num>i)break;
}
if(num<i)
{
qqq = qq;
while(num<i)
{
node ver = qqq.top();
qqq.pop();
if(!vis[ver.id])
{
ant+=ver.c;
num++;
}
}
}
if(num==i)ans = min(ans, ant);
}
if(ans==0x7fffffff)ans = 0;
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: