zoukankan      html  css  js  c++  java
  • 【刷题】LOJ 6006 「网络流 24 题」试题库

    题目描述

    假设一个试题库中有 (n) 道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取 (m) 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算法。

    输入格式

    (1) 行有 (2) 个正整数 (k)(n)(k) 表示题库中试题类型总数,(n) 表示题库中试题总数。第 (2) 行有 (k) 个正整数,第 (i) 个正整数表示要选出的类型 (i) 的题数。这 (k) 个数相加就是要选出的总题数 (m)

    接下来的 (n) 行给出了题库中每个试题的类型信息。每行的第 (1) 个正整数 (p) 表明该题可以属于 (p) 类,接着的 (p) 个数是该题所属的类型号。

    输出格式

    (i) 行输出 i: 后接类型 (i) 的题号。如果有多个满足要求的方案,只要输出一个方案。如果问题无解,则输出 No Solution!

    样例

    样例输入

    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
    

    样例输出

    1: 1 6 8
    2: 7 9 10
    3: 2 3 4 5
    

    数据范围与提示

    (2 leq k leq 20, k leq n leq 1000)

    题解

    这和圆桌聚餐问题毫无区别啊

    试题和属性分别和源点和汇点相连,属性容量为各自的需要,试题的容量只能为 (1)

    试题和自己的属性相连,容量为 (1)

    跑最大流

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=2000+10,MAXM=MAXN*MAXN+10,inf=0x3f3f3f3f;
    int n,k,e=1,beg[MAXN],cur[MAXN],level[MAXN],vis[MAXN],clk,s,t,nex[MAXM<<1],to[MAXM<<1],cap[MAXM<<1],all;
    std::queue<int> q;
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline void insert(int x,int y,int z)
    {
    	to[++e]=y;
    	nex[e]=beg[x];
    	beg[x]=e;
    	cap[e]=z;
    	to[++e]=x;
    	nex[e]=beg[y];
    	beg[y]=e;
    	cap[e]=0;
    }
    inline bool bfs()
    {
    	memset(level,0,sizeof(level));
    	level[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		for(register int i=beg[x];i;i=nex[i])
    			if(cap[i]&&!level[to[i]])level[to[i]]=level[x]+1,q.push(to[i]);
    	}
    	return level[t];
    }
    inline int dfs(int x,int maxflow)
    {
    	if(x==t||!maxflow)return maxflow;
    	vis[x]=clk;
    	int res=0;
    	for(register int &i=cur[x];i;i=nex[i])
    		if((vis[to[i]]^vis[x])&&cap[i]&&level[to[i]]==level[x]+1)
    		{
    			int f=dfs(to[i],min(maxflow,cap[i]));
    			cap[i]-=f;
    			cap[i^1]+=f;
    			res+=f;
    			maxflow-=f;
    			if(!maxflow)break;
    		}
    	vis[x]=0;
    	return res;
    }
    inline int Dinic()
    {
    	int res=0;
    	while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);
    	return res;
    }
    int main()
    {
    	read(k);read(n);
    	s=k+n+1,t=s+1;
    	for(register int i=1,x;i<=k;++i)read(x),insert(s,i,x),all+=x;
    	for(register int i=1;i<=n;++i)
    	{
    		insert(i+k,t,1);
    		int m;read(m);
    		for(register int j=1,x;j<=m;++j)read(x),insert(x,i+k,1);
    	}
    	if(Dinic()!=all)puts("No Solution!");
    	else
    		for(register int x=1;x<=k;++x)
    		{
    			printf("%d:",x);
    			for(register int i=beg[x];i;i=nex[i])
    				if(!cap[i]&&(i&1^1))printf(" %d",to[i]-k);
    			puts("");
    		}
    	return 0;
    }
    
  • 相关阅读:
    「应用界面美化」DevExpress Winform数据网格如何绑定数据
    使用Northwind数据库的 .NET Core应用你了解多少?
    如何将现有的WinForms / WPF项目转换为.NET Core?这里有你想要的答案!
    php 微信分享
    连表查询取最新时间
    filesort
    项目执行shell脚本
    redis做消息队列
    es pdf 文档
    vim 常用工具
  • 原文地址:https://www.cnblogs.com/hongyj/p/9424775.html
Copyright © 2011-2022 走看看