题目大意:
假设有来自m 个不同单位的代表参加一次国际会议。每个单位的代表数分别为ri (i =1,2,……,m)。
会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,……,n)个代表就餐。
为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法,给出满足要求的代表就餐方案。
对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。
思路:
蛮好想的一道题目。单位一边,桌子一边,如果我们把单位和桌子之间1的流量表示这个单位在这个桌子上面坐了一个人,那么显然的是,为了满足限制条件,每一单位对于每一个桌子有且仅有一条流量为1的边。同时为了满足单位来的人数限制和每张桌子坐的人数限制,在源点和汇点那里连边限制流量就好了。输出方案就乱搞
/*========================
* Author : ylsoi
* Problem : luogu3254
* Algorithm : Max_Flow
* Time : 2018.7.26
* =====================*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
using namespace std;
void File(){
freopen("luogu3254.in","r",stdin);
freopen("luogu3254.out","w",stdout);
}
const int maxm=150+10;
const int maxn=270+10;
const int maxe=maxn*maxm+10;
const int inf=0x3f3f3f3f;
int ss,tt,m,n,a[maxm],b[maxn],sum;
int cnte=1,las[maxe<<1],to[maxe<<1],beg[maxe],flow[maxe<<1],ans;
void add(int u,int v,int f){
las[++cnte]=beg[u]; beg[u]=cnte; to[cnte]=v; flow[cnte]=f;
las[++cnte]=beg[v]; beg[v]=cnte; to[cnte]=u; flow[cnte]=0;
}
struct dinic{
int num[maxn+maxm],cur[maxn+maxm];;
queue<int>qu;
bool bfs(){
memset(num,0,sizeof(num));
num[ss]=1;
qu.push(ss);
while(qu.size()){
int u=qu.front(); qu.pop();
for(int i=beg[u];i;i=las[i]){
if(!flow[i] || num[to[i]])continue;
num[to[i]]=num[u]+1;
qu.push(to[i]);
}
}
return num[tt]!=0;
}
int dfs(int u,int gap){
if(u==tt || !gap)return gap;
int ret=0,f;
for(int &i=cur[u];i;i=las[i]){
if(num[to[i]]!=num[u]+1)continue;
if((f=dfs(to[i],min(gap,flow[i])))){
gap-=f;
ret+=f;
flow[i]-=f;
flow[i^1]+=f;
}
if(!gap)break;
}
return ret;
}
void work(){
while(bfs()){
REP(i,ss,tt)cur[i]=beg[i];
ans+=dfs(ss,inf);
}
}
}T;
void init(){
scanf("%d%d",&m,&n);
REP(i,1,m){
scanf("%d",&a[i]);
sum+=a[i];
}
REP(i,1,n)scanf("%d",&b[i]);
ss=0; tt=n+m+1;
REP(i,1,m)add(ss,i,a[i]);
REP(j,1,n)add(m+j,tt,b[j]);
REP(i,1,m)REP(j,1,n)add(i,m+j,1);
}
vector<int>fuck[maxm];
int main(){
File();
init();
T.work();
if(ans==sum){
puts("1");
for(int i=2;i<=cnte;i+=2)if(!flow[i]){
if(to[i]==tt || to[i^1]==ss)continue;
fuck[to[i^1]].push_back(to[i]-m);
}
REP(i,1,m)sort(fuck[i].begin(),fuck[i].end());
REP(i,1,m){
int siz=fuck[i].size()-1;
REP(j,0,siz)printf("%d ",fuck[i][j]);
putchar('\n');
}
}
else puts("0");
return 0;
}