zoj 1023 University Entrace Examination(婚姻匹配问题)

University Entrace Examination

Time Limit: 2 Seconds      Memory Limit: 65536 KB

There is a fierce competition among high-school graduates in Iran to pass the centralized nationwide university entrance examination. Ministry of Science, Research, and Technology has set up the Education Evaluation Organization (EEO) to take care of all aspects of this big exam. This year the EEO managed to select some 150,000 students to enter universities out of 1.4 million high school graduates participated in a tough 4.5 hours multiple-choice exam. This annual event is usually preceded by a multi-billion Rial business offering preparatory courses to enthusiastic students. A few weeks after the big exam day, each participant receives a score sheet, and a list of Field-Department-University (FDU), displaying each field of study in the universities�� departments (e.g., the Software Engineering field of Computer Engineering department at Sharif University of Technology) along with their capacity for that year. The eligible participants (those who have scored enough to be allowed to declare their FDU priorities) fill out a priority indication form, and declare the FDUs they like to enter, in the order of their preference. The EEO processes the forms, and considering the total score, the participant��s FDU priority list, and some other selection rules, enters the accepted participants�� names in the list of each FDU, until all capacities are exhausted. Those who are not entered in a list are considered failed and may try again next year. Each accepted participant��s name may be entered in only one list.

One of the interesting selection rules is to persuade participants to enter universities in the vicinity of their home towns. This is to help reduce the number of requests for staying in the university dormitories.
The selection process is so complex and so sensitive to many, that EEO has decided to hire the very best programmers in Iran to design a new selection algorithm and write a completely new program for what they have been doing for years. ACM programming contest is where these programmers can be found.

There are N students S1 to SN , and M items F1 to FM , each representing one of the FDUs. There are also a number of geographic regions. For each participant, the total score, the geographic region where his/her high school diploma was awarded, and a priority list of his/her wanted FDUs are available. For each FDU, the geographic region where the corresponding university is located, and its capacity for that year is recorded.

Write a program to compute the list of accepted students with the FDU they can enter to, given the above list of input data. Your program must abide with the following rules:

1. (Local student selection rule) Suppose two students A and B have both selected F in their priority lists and F is in region R. Also suppose that score of A is greater than B's score. Then, if B is from region R (local) and A is from other regions (non-local), and B's score is greater than 70% of A's score, then B has priority over A to enter F. In all other cases A has priority over B to enter F.

2. (Fairness rule) Students should be treated according to their priority list of FDUs. That is, an accepted student will be accepted to the first possible FDU he/she can enter.

Note: We assume that scores are all different integer values.


Input

The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains N (1 <= N <= 150) and M (1 <= M <= 50) followed by N lines, each for one student. The format of these lines is Ri, Mi, K, Fi1, ��, FiK in this order. In this line, that is for student i, Ri is his/her region number, Mi is his/her score in the entrance exam, K is the number of FDUs in his/her priority list (0 <= K <= M), and his/her priority list containing the FDU numbers in order of interest. Then there are M lines, one for each FDU. Each line contains Ri, and Ci in that order, which respectively is region number of Fi (the ith FDU) and the capacity of Fi. Note that region numbers are arbitrary integers.


Output

Outputs for different test cases are separated by exactly one blank line. For each test case, you should write N lines, one for each of the N students. If student i has been accepted to FDU Fj, then ith line should contain j, and not accepted, if that student has not been accepted in any FDU of his/her interest.


Sample Input

1
9 2
1 100 2 1 2
2 80 2 2 1
1 90 1 1
2 40 1 2
2 50 1 1
1 60 1 2
2 75 1 1
1 95 1 1
2 30 1 2
1 3
2 4


Sample Output

1
2
1
2
not accepted
2
not accepted
1
2


Source: Asia 2001, Tehran (Iran)




婚姻匹配问题裸题,不同的是普通问题一男配一女,这里一个学校可以招多个学生,记录一下就好了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 200
#define eps 1e-6
using namespace std;
struct node
{
    int id,region,score,k;
}stu[N];
struct node1
{
    int region,num;
}sch[N];
struct node2
{
    int cnt;
    int manname[N];
}woman[N];
int r,n,m;
int map1[N][N],map2[N][N],man[N],times[N],vis[N];
int cmp(node a,node b)
{
    if(a.region==r)
    {
        if(b.region==r)
            return a.score>b.score;
        if(b.region!=r)
        {
            if(abs(a.score-0.7*b.score)<eps)
                return 0;
            else
                return a.score>0.7*b.score;
        }
    }
    else if(b.region==r)
    {
        if(a.region==r)
            return a.score>b.score;
        if(a.region!=r)
        {
            if(abs(b.score-0.7*a.score)<eps)
                return 1;
            else
                return b.score<0.7*a.score;
        }
    }
    else
        return a.score>b.score;
}
int cmp1(node a,node b)
{
    return a.id<b.id;
}
void makerank()
{
    int i,j;
    for(i=1;i<=m;i++)
    {
        r=sch[i].region;
        sort(stu+1,stu+n+1,cmp);
        for(j=1;j<=n;j++)
            map2[i][stu[j].id]=j;
    }
    sort(stu+1,stu+n+1,cmp1);
}
void Gale_Shapley()
{
    int flag=1,i,j,worstrank,worstrankj;
    memset(man,0,sizeof(man));
    for(i=1;i<=n;i++)
        times[i]=1;
    for(i=1;i<=n;i++)
        vis[i]=0;
    for(i=1;i<=m;i++)
        woman[i].cnt=0;
    while(flag)
    {
        flag=0;
        for(i=1;i<=n;i++)
        {
            while(!man[i]&&!vis[i])
            {
                flag=1;
                if(times[i]>stu[i].k)
                {
                    vis[i]=1;
                    break;
                }
                int name=map1[i][times[i]];
                if(woman[name].cnt<sch[name].num)
                {
                    woman[name].manname[++woman[name].cnt]=i;
                    man[i]=name;
                    times[i]++;
                }
                else if(woman[name].cnt==sch[name].num)
                {
                    worstrank=0;
                    for(j=1;j<=woman[name].cnt;j++)
                    {
                        if(map2[name][woman[name].manname[j]]>worstrank)
                        {
                            worstrank=map2[name][woman[name].manname[j]];
                            worstrankj=j;
                        }
                    }
                    if(map2[name][i]<worstrank)
                    {
                        man[woman[name].manname[worstrankj]]=0;
                        woman[name].manname[worstrankj]=i;
                        man[i]=name;
                        times[i]++;
                    }
                    else
                        times[i]++;
                }
            }
        }
    }
}
int main()
{ 
    int T,j,i;
    scanf("%d",&T);
    while(T--)
    {
        memset(map1,0,sizeof(map1));
        memset(map2,0,sizeof(map2));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            stu[i].id=i;
            scanf("%d%d%d",&stu[i].region,&stu[i].score,&stu[i].k);
            for(j=1;j<=stu[i].k;j++)
            {
                scanf("%d",&map1[i][j]);
            }
        }
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&sch[i].region,&sch[i].num);
        }
        makerank();
        Gale_Shapley();
        for(i=1;i<=n;i++)
            if(vis[i])
                printf("not accepted\n");
            else
                printf("%d\n",man[i]);
        if(T) printf("\n");
    }
    return 0;
}


ZJU_Main 主页 下一页 ZJU 题型分类 文演整理版 2008-3-23 数论: 1007 Numerical Summation of a Series 简单题,还是蛮有意思的 1045 HangOver 简单题 1049 I Think I Need a Houseboat 简单题 1028 Flip and Shift 简单题,可以DP/BFS/……,但是实际上有数学方法可直接判断出来 1026 Modular multiplication of polynomials 简单题,有比较简单的好算法 1307 Packets 简单题,不过也蛮经典的…… 1312 Prime Cuts 简单题 1334 Basically Speaking 简单题 1337 Pi 简单题 1342 Word Index 简单题 1349 Four Quarters 简单题 1350 The Drunk Jailer 简单题 1352 Number Base Conversion 简单题 1353 Unimodal Palindromic Decompositions 规模不大,所以是简单题…… 1354 Extended Lights Out 简单题 1362 Game Prediction 简单题 1365 Mileage Bank 简单题 1382 A Simple Task 简单题 1383 Binary Numbers 简单题 1403 Safecracker 简单题 1408 The Fun Number System 简单题 1486 Color the Tree 简单题 1487 Playing Cards 简单题 1489 2^x mod n = 1 简单题,应该有好算法,不过枚举就可以过…… 1503 One Person "The Price is Right" 简单题,POI Eggs的翻版 1512 Water Treatment Plants 简单题,组合计数 1526 Big Number 简单题,不过O(1)和O(n)还是有区别的:) 1529 Enigmatic Travel 简单题,不过个人感觉题目描述很令人费解 1530 Find The Multiple 简单题 1537 Playing with a Calculator 简单题 1577 GCD & LCM 简单题,分区联赛的题…… 1005 Jugs 简单题 1543 Stripies 简单题 1569 Partial Sums 简单题 1062 Trees Made to Order 简单题 1070 Bode Plot 简单题 1073 Round and Round We Go 简单题,142857,我喜欢^_^ 1078 Palindrom Numbers 简单题 1086 Octal Fractions 简单题 1199 Point of Intersection 简单题 1104 Leaps Tall Buildings 简单题 1110
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值