UVA 10092 The Problem with the Problemsetter

来源:互联网 发布:php的curl扩展 编辑:程序博客网 时间:2024/06/05 20:33

The number of students interested to participate in this year’s Intra-BUET Programming Contest is huge. Since it is very difficult to accommodate such a large number of students in our labs, we have decided to arrange a Screening Test. The test will be paper-based and may include as many as 100 analytical problems from as many as 20 categories. I have been assigned the job of setting problems for this test.
At first, the job seemed to be very easy since I was told that I would be provided with a pool of about 1000 analytical problems already divided into appropriate categories. But after getting the problems I discovered that for many problems the original authors were not sure about the appropriate categories and so they wrote down multiple category-names in the category fields. Since in the Screening Test a problem cannot be placed under more than one category and the number of problems to be set under each category is fixed, setting problems for this test is not actually easy.
I know that a program can be written that can do the job automatically. But since I don’t like writing programs, I seek your help.

Input
The input file may contain multiple test cases. Each test case begins with a line containing two integers: nk and np (2 ≤ nk ≤ 20,nk ≤ np ≤ 1000) where nk is the number of categories and np is the number of problems in the pool. The second line contains nk positive integers where the i-th integer specifies the number of problems to be included in category i (1 ≤ i ≤ nk) of the test. You may assume that the sum of these nk integers will never exceed 100. The j-th (1 ≤ j ≤ np) of the next np lines contains the category information of the j-th problem in the pool. A category specification for a problem start with a positive integer not greater than nk, specifying the number of categories in one of which this problem can be included, followed by the category numbers. Category numbers are positive integers not greater than nk.
A test case containing two zeros for nk and np terminates the input. Output
For each test case in the input print a line containing either ‘1’ or ‘0’ depending on whether or not problems can be successfully selected form the pool under the given restrictions (1 for success and 0 for failure). In case of successful selection print nk additional lines where the i-th (1 ≤ i ≤ nk) of these lines contains the problem numbers that can be included in category i. Problem numbers are positive integers not greater then np and two problem numbers must be separated by a single space character. Note that, in case of successful selection any valid selection will be accepted.

Sample Input
3 15
3 3 4
2 1 2
1 3
1 3
1 3
1 3
3 1 2 3
2 2 3
2 1 3
1 2
1 2
2 1 2
2 1 3
2 1 2
1 1
3 1 2 3
3 15
7 3 4
2 1 2
1 1
1 2
1 2
1 3
3 1 2 3 2 2 3
2 2 3
1 2
1 2
2 2 3
2 2 3
2 1 2
1 1
3 1 2 3
0 0

Sample Output
1
8 11 12
1 6 7
2 3 4 5
0

////  main.cpp//  uva 10092 The Problem with the Problem Setter////  Created by nuu_tong on 2017/11/15.//  Copyright © 2017年 apple. All rights reserved.//  二部图匹配变形,用邻接矩阵graphy[][]记录匹配情况,(注释部分用邻接表vector<int>graphy[] Runtime Error。。。。不知道为什么)**匈牙利算法**#include <iostream>#include <vector>#include <cstring>using namespace std;const int Maxn=1005;int category[25];int graphy[Maxn][Maxn];int pos[Maxn];//储存第i中题型在graphy中的起始下标int match[Maxn];bool used[Maxn];int k,p,sum;//vector <int> graphy[105];void initial(){    memset(graphy,0,sizeof(graphy));    //for(int i=0;i<105;i++)       // graphy[i].clear();    pos[1]=1;    for(int i=2;i<=k;i++)    {        pos[i]=pos[i-1]+category[i-1];//转换下标,若一种题型要出k个题,将一种题型拆成k种同题型题    }}bool dfs(int u){    for(int v=1;v<=sum;v++)    //for(int i=0;i<graphy[u].size();i++)    {        if(graphy[u][v]&&!used[v])       //int v=graphy[u][i];        //if(!used[v])        {            used[v]=true;            if(match[v]==-1||dfs(match[v]))            {                match[v]=u;                return true;            }        }    }    return false;}void MaxMatch(){    int res=0;    for(int i=1;i<=sum;i++)    {        match[i]=-1;    }    for(int i=1;i<=p;i++)    {        memset(used,false,sizeof(used));        if(dfs(i))            res++;    }    }    if(res==sum)    {        cout<<'1'<<endl;        for(int i=1;i<=k;i++)        {            for(int k=0;k<category[i];k++)            {                if(k>0)                    cout << " ";                cout<<match[k+pos[i]];            }            cout<<endl;        }    }    else        cout<<'0'<<endl;}int main(){    int n,c;    while(cin>>k>>p)    {        if(k==0&&p==0)            break;        sum=0;        for(int i=1;i<=k;i++)        {            cin>>category[i];//输入每个类别题目的数量            sum+=category[i];//记录题目总数        }        initial();        for(int i=1;i<=p;i++)        {            cin>>n;            for(int j=0;j<n;j++)            {                cin>>c;                for(int k=0;k<category[c];k++)                {                    //graphy[i].push_back(k+pos[c]);                    graphy[i][k+pos[c]]=c;                }            }        }        MaxMatch();    }    return 0;}

类似题: uva 10045 My T-shirt suits me

#include <iostream>#include <cstring>#include <vector>#include <map>using namespace std;map<string,int> size;vector<int> graphy[35];int match[35];bool used[40];int N,M;void initial(){    for(int i=0;i<35;i++)        graphy[i].clear();}bool dfs(int u){    for(int i=0;i<graphy[u].size();i++)    {        int v=graphy[u][i];        if(!used[v])        {            used[v]=true;            if(match[v]==-1||dfs(match[v]))            {                match[v]=u;                return true;            }        }    }    return false;}int MaxMatch(){    int res=0;    for(int i=0;i<N;i++)    {        match[i]=-1;    }    for(int i=0;i<M;i++)    {        memset(used,0,sizeof(used));        if(dfs(i))            res++;    }    return res;    }int main(){    int L,ans;    cin>>L;    string s1,s2;    string suitSize[6]={"XXL", "XL", "L", "M", "S", "XS"};    for(int i=0;i<6;i++)    {        size.insert(pair<string,int>(suitSize[i],i));// 将六种尺码转为int型,存在map中    }    while (L--)    {        cin>>N>>M;        int num=N/6;        initial();        for(int i=0;i<M;i++)        {            cin>>s1>>s2;            for(int k=0;k<num;k++)            {                graphy[i].push_back(size[s1]*num+k);//将同一型号衣服拆成num件同样的衣服,转化下标(例如num=3时,XXL号衣服下标为0,1,2)                graphy[i].push_back(size[s2]*num+k);            }        }    ans=MaxMatch();        if(ans==M)            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }    return 0;}
原创粉丝点击