【题解】Luogu P2763 试题库问题

原题传送门

这题很简单啊

从源点向k类题目分别连流量为所需数量的边

从每道题向汇点连一条流量为1的边(每题只能用1次)

从类型向对应的题目连一条流量为1的边

跑一边最大流

如果最大流小于所需题目数量,就无解

否则对于每个类型,看每道题是否要选

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define M 80005
#define N 2005
//#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
    return a<b?a:b;
}
struct node{
    int to,nxt,v;
}e[M];
int head[N],cnt=1;
inline void add(register int u,register int v,register int val)
{
    e[++cnt]=(node){v,head[u],val};
    head[u]=cnt;
}
int n,k,s,t,nn,maxflow=0,sum=0;
int dep[N],gap[N],cur[N];
inline void bfs()
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    dep[t]=0;
    ++gap[dep[t]];
    queue<int> q;
    q.push(t);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(register int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;
            if(dep[v]!=-1)
                continue;
            q.push(v);
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
inline int dfs(register int u,register int flow)
{
    if(u==t)
    {
        maxflow+=flow;
        return flow;
    }
    int used=0;
    for(register int i=cur[u];i;i=e[i].nxt)
    {
        cur[u]=i;
        int v=e[i].to;
        if(e[i].v&&dep[v]+1==dep[u])
        {
            int tmp=dfs(v,Min(e[i].v,flow-used));
            if(tmp)
            {
                e[i].v-=tmp;
                e[i^1].v+=tmp;
                used+=tmp;
            }
            if(used==flow)
                return used;
        }
    }
    --gap[dep[u]++]==0?dep[s]=nn+1:++gap[dep[u]];
    return used;
}
inline void ISAP()
{
    bfs();
    while(dep[s]<nn)
    {
        memcpy(cur,head,sizeof(head));
        dfs(s,inf);
    }
}
int main()
{
    k=read(),n=read();
    s=0,t=k+n+1;
    for(register int i=1;i<=k;++i)
    {
        int x=read();
        add(s,i,x),add(i,s,0),sum+=x;
    }
    for(register int i=1;i<=n;++i)
    {
        int p=read();
        for(register int j=1;j<=p;++j)
        {
            int x=read();
            add(x,i+k,1),add(i+k,x,0);
        }
        add(i+k,t,1),add(t,i+k,0);
    }
    nn=n+k+2;
    ISAP();
    if(maxflow==sum)
        for(register int u=1;u<=k;++u)
        {
            write(u),putchar(':'),putchar(' ');
            for(register int i=head[u];i;i=e[i].nxt)
                if(e[i].to!=0&&e[i].v==0)
                    write(e[i].to-k),putchar(' ');
            puts("");
        }
    else
        puts("No Solution!");
    return 0;
}

原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10339726.html

时间: 2024-08-30 17:12:55

【题解】Luogu P2763 试题库问题的相关文章

luogu P2763 试题库问题

本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲. 最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要的量,对于每一个试题,从源点连一条capacity为1的边到他,从他对每一个其所属的编号种类连一条capacity为1的边,求最大流即可,再找出最小割即可 #include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&

洛谷P2763 试题库问题

题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. «编程任务: 对于给定的组卷要求,计算满足要求的组卷方案. 输入输出格式 输入格式: 第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000) k 表示题库中试题类型总数

P2763 试题库问题

\(\color{#0066ff}{题目描述}\) ?问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ?编程任务: 对于给定的组卷要求,计算满足要求的组卷方案. \(\color{#0066ff}{输入格式}\) 第1行有2个正整数k和n (2<=k<=20, k<=n<=1000),k 表示题库中试题类型总数,n 表示题库中试题总数. 第2

COGS732. [网络流24题] 试题库

«问题描述:假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.«编程任务:对于给定的组卷要求,计算满足要求的组卷方案.«数据输入:由文件testlib.in提供输入数据.文件第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000)k 表示题库中试题类型总数,n 表示题库中试题总数.第2 行有k 个正整数,第i 个正整数表示要选出的类型i

数据库笔试面试题库(Oracle、MySQL等)

数据库笔试面试题库(Oracle.MySQL等) ⊙ [DB笔试面试67]在Oracle中,关于表分区下列描述不正确的是()⊙ [DB笔试面试65]在Oracle中,哪一种表分区方式建议的分区数是2的幂(2.4.8等),以获得最平均的数据发布()⊙ [DB笔试面试63]要以NAME's address is ADDR格式返回数据,以下SQL语句正确的是⊙ [DB笔试面试61]以下关于数据模型要求错误的是()⊙ [DB笔试面试59]以下关于视图叙述不正确的是()⊙ [DB笔试面试57]下列关于SQ

试题库问题 2011-12-29

算法实现题8-7 试题库问题(习题 8-18) ´问题描述: 假设一个试题库中有n道试题. 每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ´编程任务: 对于给定的组卷要求,计算满足要求的组卷方案. ´数据输入: 由文件input.txt提供输入数据. 文件第1行有2个正整数n和k (2 <=k<= 20, k<=n<= 1000) k 表示题库中试题类型总数,n 表示题库中试题

[网络流24题]试题库问题

Description 假设一个试题库中有$n$道试题,每道试题都标明了所属类别,同一道题可能有多个类别属性.现要从题库中抽取$m$道题组成试卷,并要求试卷包含指定类型的试题.求一个满足要求的组卷方案. Input 第$1$行有$2$个正整数$n,k,k$表示题库中试题类型总数,$n$表示题库中试题总数. 第$2$行有$k$个正整数,第$i$个正整数表示要选出的类型$i$的题数$a_i$.这$k$个数相加就是要选出的总题数$m$. 接下来的$n$行给出了题库中每个试题的类型信息.每行的第$1$个

试题库找答案小程序的开发

期末考试考完无聊在刷试题库.然后CY来我寝室,提醒我可以搞个自动在excel里找答案的程序,他给了思路之后就马上开始动工. 所谓带有我们学校特色的试题库就是下载excel表格,作业和考试题都在网页上,我们要在excel里找答案.把这个过程理了一下,程序主要实现以下功能: 1.监视剪贴板的变化: 2.如果检测到剪贴板内容变化,则根据剪贴板里的内容,利用正则表达式在试题库的题目里找到第一个最匹配的题目: 3.在控制台输出答案. 考虑到python有丰富的库,要连接到excel或者监视剪贴板不是什么麻

网络流 24题 试题库问题

试题库问题 题目描述 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.具体的描述见输入格式. 输入格式 文件第1行有2个正整数k和n (2 <=k<= 20,k<=n<= 1000) k表示题库中试题类型总数,n表示题库中试题总数.第2行有k个正整数,第i个正整数表示要选出的类型i的题数.这k个数相加就是要选出的总题数m.接下来的n行给出了题库中每个试题的类