ZOJ-3715-Kindergarten Election

来源:互联网 发布:淘宝客如意投质量评价 编辑:程序博客网 时间:2024/05/04 03:09
Kindergarten Election
Time Limit: 2 Seconds      Memory Limit: 65536 KB
At the beginning of the semester in kindergarten, the n little kids (indexed from 1 to n, for convenience) in class need to elect their new leader.

The ith kid will vote for his best friend fi (where 1 ≤ fi ≤ n, and it's too shame to vote for yourself, so fi ≠ i). And the kid who gets the most votes will be the leader. If more than one kids who get the largest number of votes, there will be multiple leaders in the new semester.


Little Sheldon (the kid with index 1) is extremely vain, and he would like to be the ONLY leader. (That means the number of votes he gets should strictly larger than any other.) Soon Sheldon found that if he give ci candies to the ith kid, the ith kid would regard Sheldon as the new best friend, and of course vote for Sheldon.


Every kid including Sheldon loves candies. As an evil programmer, please help the evil Sheldon become the ONLY leader with minimum cost of candies. By the way, Sheldon should vote for any one he wants EXCEPT himself.

Input


There are multiple test cases. The first line of input contains an integer T (T ≤ 100) indicating the number of test cases. Then T test cases follow.


The first line of each case contains one integer: n (3 ≤ n ≤ 100) -- the number of kids in class.


The second line contains n-1 integers: fi (1 ≤ fi ≤ n, fi ≠ i, and 2 ≤ i ≤ n) -- represents that the best friend of ith kid is indexed with fi.


The third line contains n-1 integers: ci (1 ≤ ci ≤ 1000, and 2 ≤ i ≤ n) -- represents that if Sheldon gave ci candies to the ith kid, the ith kid would vote Sheldon, instead of their old best friend fi, as the new semester leader.


Output

For each test case, print the minimal cost of candies to help Sheldon become the ONLY leader.

Sample Input

2
4
1 1 2
1 10 100
3
3 2
1 10
Sample Output

0

11

题目链接:Kindergarten Election

题意:有n个人要选一个领导,1号想通过买通别人投自己,来让自己成为领导,现给出编号2~n的人投票对象,以及买通他所需花费,求1号能当选领导所需最小花费,票不能投给自己。

思路:很容易就想到两种取法,1.买通投了 和1号票数相同 的人

  2.买通没投给1号,且花费最小 的人

但是要怎样才能轻松考虑到这两点呢?自己做的时候想得好复杂,最后受不了了看了别人的思路。

最终状态肯定是确定的,也就是最终1号的票数,n<=100,所以可以枚举最终状态。

最终状态肯定是只能是1号的状态,所以就要把其他人的状态都控制低于这个值,而且优先选花费最小的。

当然,以这样的思路去做的话,要保证1号自己达到了这个值,没有的话选最小花费的。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct node{    int f,c,id;} p[110],u[110];int v[1010], use[1010];int cmp1(node a,node b){    if(a.f==b.f)        return a.c<b.c;    return a.f<b.f;}int cmp2(node a,node b){    return a.c<b.c;}int main(){    int T, n, tmp, num, ans;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        memset(v, 0, sizeof(v));        for(int i = 2; i <= n; i++)        {            scanf("%d",&p[i].f);            p[i].id = i;            v[p[i].f] ++;        }        for(int i = 2; i <= n; i++)            scanf("%d",&p[i].c);        sort(p+2, p+1+n, cmp1);//按投票对象的ID        for(int i = 2; i <= n; i++)            u[i] = p[i];        sort(u+2, u+1+n, cmp2);//按买通所需花费        ans = 1e5+10;        for(int i = max(2, v[1]); i <= n; i++) //枚举我能被选的最终票数        {//n >= 3,所以我最少也要两票            tmp = 0;            num = v[1];            memset(use,0,sizeof(use));            for(int j = 2; j <= n; j++)            {                if(v[j] > i-1)//如果第j个人的票数>= i                {                    int cnt = v[j]-i+1;//让这个人票数低于i票还需买通的人数                    for(int k = 2; k <= n; k++) //将投了这个人的人买通投我                    {//此处已经排序,优先选花费最少的                        if(p[k].f != j) continue;                        use[p[k].id] = 1;                        tmp += p[k].c; //当前花费                        num ++; //我的票数增加                        cnt --;                        if(!cnt) break;                    }                }            }            if(num < i) //我的票数没达到i            {                for(int k = 2; k <= n; k++)                {//优先选花费最少的                    if(num >= i) break;                    if(u[k].f == 1 || use[u[k].id] == 1) continue;                    tmp += u[k].c;                    num ++;                }            }            ans = min(ans, tmp);        }        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击