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;
    }
    
  • 相关阅读:
    实验室 Linux 集群的管理常用命令
    python操作MySQL数据库
    python 文件操作总结
    MySQL常用的操作整理
    机器学习模型数据结构:logistic regression, neural network, convolutional neural network
    Python并发编程之线程池/进程池--concurrent.futures模块
    python3.5实现购物车
    Centos上安装python3.5以上版本
    [Python]关于return逻辑判断和短路逻辑
    [Python]返回函数,装饰器拾遗
  • 原文地址:https://www.cnblogs.com/hongyj/p/9424775.html
Copyright © 2011-2022 走看看