题目描述 Description

假设有来自n 个不同单位的代表参加一次国际会议。每个单位的代表数分别为
ri ni , =1,2,, 。会议餐厅共有m张餐桌,每张餐桌可容纳ci( 1,2, ,m) i =  个代表就餐。
为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法,
给出满足要求的代表就餐方案。
«编程任务:
对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。

输入描述 Input Description

第1行有2 个正整数m和n,m表示单位数,n表
示餐桌数,1<=m<=150, 1<=n<=270。文件第2 行有m个正整数,分别表示每个单位的代表
数。文件第3 行有n个正整数,分别表示每个餐桌的容量。

输出描述 Output Description

如果问题有解,在文件第
1 行输出1,否则输出0。接下来的m行给出每个单位代表的就餐桌号。如果有多个满足要
求的方案,只要输出1 个方案。

样例输入 Sample Input

4 5
4 5 3 5
3 5 2 6 4

样例输出 Sample Output

1
1 2 4 5
1 2 3 4 5
2 4 5
1 2 3 4 5

题目可以再这里提交:http://wikioi.com/homework/23/

应该SPJ的。

分析:二分多重匹配,源点S向每个单位建边,容量为该单位的人数,每个圆桌向汇点T建边,容量为圆桌可以容纳的人数,每个单位向每个圆桌建边,容量为1,跑最大流即可。

代码:

//Isap算法,复杂度O(n^2m)
#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;   //记得必要的时候改成无符号
const int maxn=505;
const int maxm=1000005;
const int INF=1000000000;
struct EdgeNode
{int from;int to;int cost;int next;
}edge[maxm];
int head[maxn],cnt;
void add(int x,int y,int z)
{edge[cnt].from=x;edge[cnt].to=y;edge[cnt].cost=z;edge[cnt].next=head[x];head[x]=cnt++;edge[cnt].from=y;edge[cnt].to=x;edge[cnt].cost=0;edge[cnt].next=head[y];head[y]=cnt++;
}void init()
{cnt=0;memset(head,-1,sizeof(head));
}int S,T,n,m;
int d[maxn],gap[maxn],curedge[maxn],pre[maxn];
//curedge[]为当前弧数组,pre为前驱数组int sap(int S,int T,int n)  //n为点数
{int cur_flow,flow_ans=0,u,tmp,neck,i;memset(d,0,sizeof(d));memset(gap,0,sizeof(gap));memset(pre,-1,sizeof(pre));for(i=0;i<=n;i++)curedge[i]=head[i]; //初始化当前弧为第一条邻接表gap[0]=n;u=S;while(d[S]<n)             //当d[S]>=n时,网络中肯定出现了断层{if(u==T){cur_flow=INF;for(i=S;i!=T;i=edge[curedge[i]].to){                           //增广成功,寻找瓶颈边if(cur_flow>edge[curedge[i]].cost){neck=i;cur_flow=edge[curedge[i]].cost;}}for(i=S;i!=T;i=edge[curedge[i]].to){                             //修改路径上的边容量tmp=curedge[i];edge[tmp].cost-=cur_flow;edge[tmp^1].cost+=cur_flow;}flow_ans+=cur_flow;u=neck;                     //下次增广从瓶颈边开始}for(i=curedge[u];i!=-1;i=edge[i].next)if(edge[i].cost&&d[u]==d[edge[i].to]+1)break;if(i!=-1){curedge[u]=i;pre[edge[i].to]=u;u=edge[i].to;}else{if(0==--gap[d[u]])break;    //gap优化curedge[u]=head[u];for(tmp=n,i=head[u];i!=-1;i=edge[i].next)if(edge[i].cost)tmp=min(tmp,d[edge[i].to]);d[u]=tmp+1;++gap[d[u]];if(u!=S)u=pre[u];           //重标号并且从当前点前驱重新增广}}return flow_ans;
}vector<int>V[maxn];
int main()
{int x,y,i,j,sum;while(~scanf("%d%d",&n,&m)){init(); S=0; T=n+m+1; sum=0;for(i=1;i<=n;i++){scanf("%d",&x); sum+=x;add(S,i,x);for(j=1;j<=m;j++)add(i,n+j,1);}for(i=1;i<=m;i++){scanf("%d",&x);add(n+i,T,x);}if(sum!=sap(S,T,T+1))printf("0\n");else{printf("1\n");for(i=1;i<=n;i++)V[i].clear();for(i=0;i<cnt;i++){x=edge[i].from; y=edge[i].to;if(x>=1&&x<=n&&y>n&&y<=n+m&&edge[i].cost==0)V[x].push_back(y-n);}for(i=1;i<=n;i++)sort(V[i].begin(),V[i].end());for(i=1;i<=n;i++){for(j=0;j<V[i].size();j++){if(j==0)printf("%d",V[i][j]);else printf(" %d",V[i][j]);}printf("\n");}}}return 0;
}

圆桌问题 二分多重匹配+输出解相关推荐

  1. POJ - 2584 T-Shirt Gumbo 二分多重匹配

    题目链接 题意:二分多重匹配的裸题,与匈牙利算法不同的之前的男女匹配不同,这个题目的题意是每一个人可以选择多种型号的衣服,并且每一种衣服可以很多人穿,但是每件衣服有数量限制,问最多有多少匹配数. 我们 ...

  2. 【网络流24题】解题报告:E 、圆桌问题(最大流求二分图多重匹配)

    E .圆桌问题(最大流求二分图多重匹配)[省选/NOI- ] 可以直观的想到,二分图的左边是单位,右边是桌子 由于题目的限制 每个单位只能在一个桌子坐一个人 所以我们就把每个单位向各个桌子连一道流量为 ...

  3. poj2112(floyd+二分+二分图多重匹配)

    (感觉是一个比较基础的二分图多重匹配) 题目意思大概就是有K个挤奶点,C个奶牛,一个挤奶点能容下M个奶牛,问如果所有奶牛都被放入挤奶点时,距离最远奶牛得最短距离(距离可以经过其他点) 首先看到可以经过 ...

  4. POJ - 2112 Optimal Milking(二分+二分图最大匹配-多重匹配(修改匈牙利实现)+Floyd求最短路)

    题目链接:点击查看 题目大意:给出n个牛奶机器,再给出m只奶牛,每个机器只能让最多k只牛一起挤奶,现在问如何分配奶牛,能让最远的那只奶牛到达机器的距离最小 题目分析:很综合的一道题目了,不算很难,但比 ...

  5. [tyvj1935 Poetize3]导弹防御塔 (二分图多重匹配)

    传送门 Description Freda控制着N座可以发射导弹的防御塔.每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚.在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚 ...

  6. POJ - 2289 Jamie's Contact Groups(二分图多重匹配)

    题目链接:点击查看 题目大意:给出n个联系人,以及m个分组,现在需要将n个联系人分到m个分组中,需要满足让人数最多的组的人数最少,输出这个值 题目分析:因为是让最大值最小,所以肯定是要用二分解决,因为 ...

  7. POJ - 3189 Steady Cow Assignment(二分图多重匹配)

    题目链接:点击查看 题目大意:给出n只奶牛以及m个牛棚,接下来给出一个n*m的矩阵,给出每一只奶牛对于每个牛棚的喜爱度,按照降序给出,从rank1到rankm,现在问如何分配牛棚能让所有奶牛中最高的r ...

  8. CH - 6803 导弹防御塔(二分图最大匹配-多重匹配(拆点法))

    题目链接:点击查看 题目大意:给出n个炮塔,再给出m个敌人,每个炮塔都可以持续发射导弹,不过发射导弹的时间是t1秒,炮塔冷却的时间是t2分钟,炮弹飞行的速度是v,炮塔和敌人之间的距离按照欧几里得距离计 ...

  9. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

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

最新文章

  1. Java集合类: Set、List、Map、Queue区别及应用
  2. Spring Boot 自动配置之条件注解
  3. 【Paper】2021_Analysis of the Consensus Protocol of Heterogeneous Agents with Time-Delays
  4. [NOTE] WindowsLinux常用环境变量
  5. [转]如何让DIV固定在页面的某个位置而不随着滚动条随意滚动
  6. 转 安装PHP出现make: *** [sapi/cli/php] Error 1 解决办法
  7. Android组件间的数据传输
  8. ubuntu上安装python3.7教程_Ubuntu安装python 3. 7
  9. docker学习记录 docker 脚本----redis,zookeeper,kafka(三)
  10. Linux下安装zabbix详细介绍
  11. 加拿大计算机硕士留学移民,加拿大硕士留学移民深度解析,纯干货
  12. iOS webp图片展示处理
  13. excel如何快速批量翻译单词
  14. 毕业了能考计算机二级考试,大学毕业一定要考计算机二级考试吗?
  15. 5g理论速度_5g速度有多快
  16. PCI-E 1X金手指封装
  17. python中strip函数和split函数
  18. linux下流量监控统计软件,Linux服务器网卡流量统计监控软件vnStat
  19. 2022中国智能巡检机器人行业发展研究白皮书
  20. GIT仓库(本地仓库)

热门文章

  1. Makefile中的ifeq 多条件使用
  2. Discriminative Sounding Objects Localization via Self-supervised Audiovisual Matching
  3. 移动端h5落地页总结(vue cli+vant)
  4. java tlab_「原创」JVM系列05|TLAB上分配
  5. 移动APP测试(一)
  6. python提取两列数据对比_使用Python的Dataframe取两列时间值相差一年的所有行方法...
  7. eclipse alt+←方向 快捷键失效-ikbc F108机械键盘的大坑
  8. 利兹大学开发的一款探测无人机系统可以帮助救援人员看到建筑物内部
  9. win10误删微软商店,重新安装微软商店的方法
  10. 西红柿营养价值高 保健养生常梳头