题目大意:
有m个不同单位的代表人来参加会议,每个单位的人数是确定的,会议餐厅有n张桌子,每个桌子能容纳的人数也是确定的,现在希望来自一个单位的人不在同一个桌子上就餐,求出满足要求的就餐方案,并输出方案;
思路分析:
①:设立一个源点,连向每一个单位,流量为每个单位来参加会议的人数;
②:从每个单位向每个桌子连一条边,流量为1,保证了每个桌子每个单位只能有一个人;
③:设立一个汇点,从每个桌子向汇点连一条边,流量为每个餐桌能容纳的人数;
代码实现:
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=430,M=33250,INF=0x3f3f3f3f;
int n,m,s,t,top,head[N],gap[N],cur[N],dis[N],pre[N];
struct Edge{
int to,next,flow;
Edge(int _to=0,int _next=0,int _flow=0):to(_to),next(_next),flow(_flow){}
}edge[M];
void Addedge(int from,int to,int flow){
edge[top]=Edge(to,head[from],flow);
head[from]=top++;
edge[top]=Edge(from,head[to],0);
head[to]=top++;
}
void Bfs(){
queue<int> q;
memset(gap,0,sizeof(gap));
memset(dis,-1,sizeof(dis));
gap[0]=1,dis[t]=0;
q.push(t);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i+1;i=edge[i].next){
if(dis[edge[i].to]==-1){
dis[edge[i].to]=dis[u]+1;
gap[dis[edge[i].to]]++;
q.push(edge[i].to);
}
}
}
}
int Sap(){
Bfs();
memset(pre,-1,sizeof(pre));
for(int i=0;i<=t;++i) cur[i]=head[i];
int u=s,cur_flow,max_flow=0,neck,tmp;
while(dis[s]<=t){
if(u==t){
cur_flow=INF;
for(int i=s;i!=t;i=edge[cur[i]].to){
if(cur_flow>edge[cur[i]].flow){
neck=i;
cur_flow=edge[cur[i]].flow;
}
}
for(int i=s;i!=t;i=edge[cur[i]].to){
tmp=cur[i];
edge[tmp].flow-=cur_flow;
edge[tmp^1].flow+=cur_flow;
}
max_flow+=cur_flow;
u=neck;
}
int i;
for(i=cur[u];i+1;i=edge[i].next)
if(edge[i].flow&&dis[u]==dis[edge[i].to]+1) break;
if(i!=-1){
cur[u]=i;
pre[edge[i].to]=u;
u=edge[i].to;
}else{
if(--gap[dis[u]]==0) break;
cur[u]=head[u];
int mindis=t;
for(i=head[u];i+1;i=edge[i].next){
if(edge[i].flow&&mindis>dis[edge[i].to])
mindis=dis[edge[i].to];
}
dis[u]=mindis+1;
gap[dis[u]]++;
if(u!=s) u=pre[u];
}
}
return max_flow;
}
int main(){
freopen("roundtable.in","r",stdin);
freopen("roundtable.out","w",stdout);
memset(head,-1,sizeof(head));
top=s=0;
int va,sum=0;
scanf("%d%d",&m,&n);
t=n+m+1;
for(int i=1;i<=m;++i){
scanf("%d",&va);
sum+=va;
Addedge(s,i,va);
}
for(int i=1;i<=n;++i){
scanf("%d",&va);
Addedge(i+m,t,va);
}
for(int i=1;i<=m;++i){
for(int j=1;j<=n;++j) Addedge(i,j+m,1);
}
int res=Sap();
if(res<sum) printf("0\n");
else{
printf("1\n");
for(int i=1;i<=m;++i){
for(int j=head[i];j+1;j=edge[j].next)
if(!edge[j].flow) printf("%d ",edge[j].to-m);
printf("\n");
}
}
}