ZOJ 3715 Kindergarten Election(枚举+贪心)

来源:互联网 发布:淘宝运营助理要做多久 编辑:程序博客网 时间:2024/05/17 01:58

Kindergarten Election

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
Hint

In the first case,

If Sheldon vote for 2nd kid, the 2nd kid and Sheldon will both have 2 votes. In this case, Sheldon have to pay 100 candies to the 4th kid, and get 3 votes to win;
If Sheldon vote for 3rd or 4th kid, Sheldon will win with 2 votes without sacrifice any candy.

题意:有n个学生要选出班长编号从1到n,1号人比较虚荣,想自己当班长,每个人都可以投一票给自己心目中的人但不能投给自己,只要谁的票数最高谁就可以当班长。给出每个人心目中的投票人,以及贿赂每个人所需要的糖果,(只要你给了那个人一定数目的糖果他就会支持你) 。问1号如果当班长的话,最少需要的糖果数。(1号可以投给任何人)

思路:由于n比较小,所以我们可以枚举1当班长时的得票数x,然后再将其他人的得票数大于x的变为x-1, (减少的给1并且减少的肯定是所需糖果树最少的),然后检查最后1的得票数,如果大于x那么肯定无解,如果等于x,只要保证2到n中有得票数<= x - 2的即可。如果小于x,那么从剩下没有支持1的中,找出所需糖果树最少的来贿赂得票知道等于x为止。

代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=105;const int inf=0x3f3f3f3f;struct node{    int vo,co;} q[maxn];int vis[maxn],num[maxn];bool cmp(node a,node b){    return a.co<b.co;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(num,0,sizeof(num));        int n,i,j;        scanf("%d",&n);        for(i=2; i<=n; ++i)        {            scanf("%d",&q[i].vo);            ++num[q[i].vo];        }        for(i=2; i<=n; ++i)            scanf("%d",&q[i].co);        sort(q+2,q+n+1,cmp);        int ans=inf,tot;        for(i=num[1]; i<n; ++i)//枚举目标票数        {            memset(vis,0,sizeof(vis));            memset(num,0,sizeof(num));            for(j=2; j<=n; ++j)                ++num[q[j].vo];            int temp=num[1];            tot=0;            for(j=2; j<=n; ++j)//将其他人的得票数大于i的变为i-1            {                if(q[j].vo!=1)                {                    if(num[q[j].vo]>=i)                    {                        --num[q[j].vo];                        ++temp;                        tot+=q[j].co;                        vis[j]=1;                    }                }            }            if(temp==i)            {                for(j=2; j<=n; ++j)//是否有得票数小于temp-1if(num[j]<temp-1)                        break;                if(j<=n)                    ans=min(ans,tot);            }            else if(temp<i)            {                for(j=2; j<=n&&temp<i; ++j)//从没有支持1的人中选出所需糖果数最少的人进行贿赂,使得1的得票数为i                {                    if(!vis[j]&&q[j].vo!=1)                    {                        --num[q[j].vo];                        ++temp;                        vis[j]=1;                        tot+=q[j].co;                    }                }                ans=min(ans,tot);            }        }        printf("%d\n",ans);    }    return 0;}



总结:对于数据比较小的,要想到枚举啊!

1 0
原创粉丝点击