title
LUOGU 2763
Title Description
«Problem description:
Suppose there are n a test database test questions. Each test questions are marked Category. The same questions may have more than one category attributes. Extract from the current exam paper composed of m questions. And requested the papers contain the specified type of questions. Try to design a test paper algorithm requirements are met.
«Programming tasks:
For a given test paper requires calculating program to meet the requirements of the test paper.
Input and output format
input format:
Line 1 has two positive integers k and n-(2 <= k <= 20 is, k <= n-<= 1000)
k represents the total number of questions in the exam type, n represents the total number of exam questions. The second row has k a positive integer, the i-th number of questions to be a positive integer selected type i. This sum is the total number k m be the number of the selected title. The next line gives the n type of exam information for each of the questions. Each row of positive integers p 1 indicates that the problem may be of the type p, the number p is type number followed by the title belongs.
Output formats:
I-th row output "i:" Question followed by the type i. If there are a plurality of programs to meet the requirements, so long as the output of a program. If the problem is no solution, output "No Solution!".
Input Output Sample
Input Sample # 1:
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
Output Sample # 1:
1: 1 6 8
2: 7 9 10
3: 2 3 4 5
Explanation
Thank @PhoenixEclipse provide spj
analysis
This question is a bipartite graph matching network multiple streams, and round-table issues like the fact that essentially the same .
Simple meaning of the questions:
Have questions, types. Each type is a collection of questions . From which you choose Road kind of questions, each question can only be selected once. Seeking a viable option.
Consider limiting each question with a number of selected traffic. And each question for each type and configuration points.
First, from the to even a flow side, i.e., each question is selected only once;
Then from to even a flow Side, namely the need for each type of election Road;
At last ,From give even edges, i.e., each question may be selected in the name of the appropriate type.
That is, all those programs subject to the type of edge even in full flow. If no solution flow dissatisfaction.
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10,maxm=3e4+10,maxk=25,inf=1e9;
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
template<typename T>inline void write(T x)
{
if (!x) { putchar('0'); return ; }
if (x<0) putchar('-'),x=-x;
T num=0,ch[20];
while (x) ch[++num]=x%10+48,x/=10;
while (num) putchar(ch[num--]);
}
int ver[maxm<<1],edge[maxm<<1],Next[maxm<<1],head[maxn],len=1;
inline void add(int x,int y,int z)
{
ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
ver[++len]=x,edge[len]=0,Next[len]=head[y],head[y]=len;
}
int s,t;
int dist[maxn];
inline bool bfs()
{
queue<int>q;
memset(dist,0,sizeof(dist));
q.push(s);dist[s]=1;
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=head[x]; i; i=Next[i])
{
int y=ver[i];
if (edge[i] && !dist[y])
{
dist[y]=dist[x]+1;
if (y==t) return 1;
q.push(y);
}
}
}
return 0;
}
inline int get(int x,int low)
{
if (x==t) return low;
int tmp=low;
for (int i=head[x]; i; i=Next[i])
{
int y=ver[i];
if (edge[i] && dist[y]==dist[x]+1)
{
int a=get(y,min(tmp,edge[i]));
if (!a) dist[y]=0;
edge[i]-=a;
edge[i^1]+=a;
if (!(tmp-=a)) break;
}
}
return low-tmp;
}
int main()
{
int k,n,sum=0,ans=0;
read(k);read(n);
s=0,t=n+k+1;
for (int i=1,f; i<=k; ++i) read(f),sum+=f,add(s,i,f);
for (int i=1,p; i<=n; ++i)
{
read(p);
for (int j=1,x; j<=p; ++j) read(x),add(x,i+k,1);
}
for (int i=1; i<=n; ++i) add(i+k,t,1);
while (bfs()) ans+=get(s,inf);
if (ans!=sum) return puts("No Solution!"),0;
for (int x=1; x<=k; ++x)
{
write(x),putchar(':'),putchar(' ');
for (int i=head[x]; i; i=Next[i])
{
int y=ver[i];
if (y!=s && !edge[i]) write(y-k),putchar(' ');
}
puts("");
}
return 0;
}