网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - PowerOJ1740 - 有SPJ - 推荐
题目传送门 - CodeVS1905 - 无SPJ - 0% 通过率(可以用来看题目)
题意概括
有n支队伍,m个组。第i支队伍有a[i]个人,第i个组最多可以有b[i]个人。
现在要求任何两个同队队员不可位于同一组,求是否有方案满足。
输出第一行,表示是否有,如果有,是1,没有的话,输出0;
如果有,接下来n行,第i行a[i]个数,表示第i支队伍的每个人被安排的组号。
有SPJ,只要输出任意一种方案即可。
题解
其实就是一个网络流的水题。
前置技能 - 网络流(传送门)
对于n支队伍,每只队伍一个点;对于m个组(餐桌),每个组一个点。
另外地,建立一个源点和一个汇点。
连接源点和队伍点,对于队伍i,该边的容量为a[i];
连接每一个组的点和汇点,对于组i,该边的容量为b[i];
对于每一个队伍,向每个组连一条边,容量为1。
那么图就构建完了。
至于证明,不解释了。
然后跑一跑最大流,就算出了最大匹配数。
其实,我们可以发现,这是一个二分图多重匹配问题。
如果无法全部匹配,则输出0,
否则输出1,再考虑。
然后对于连接二分图左右两端的边,如果容量为1,那么这条边就是被选择的,那么该边所连接的两个节点,“队伍点”对应“组点”,然后这样就可以把所有的匹配全部还原。
具体操作见代码。
代码
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N=,M=N*N,Inf=<<;
struct Edge{int x,y,cap,flow,nxt,flag;};
struct Graph{
int cnt,s,t,n,fst[N],dist[N],cur[N],num[N],p[N],head,tail,q[N];
Edge e[M];
void set(int S,int T,int nn){
s=S,t=T,n=nn,cnt=,memset(fst,,sizeof fst);
}
void add(int a,int b,int c,int d){
e[++cnt].x=a,e[cnt].y=b,e[cnt].cap=c,e[cnt].flow=,e[cnt].flag=d,e[cnt].nxt=fst[a],fst[a]=cnt;
e[++cnt].x=b,e[cnt].y=a,e[cnt].cap=,e[cnt].flow=,e[cnt].flag=,e[cnt].nxt=fst[b],fst[b]=cnt;
}
void re_bfs(){
memset(dist,-,sizeof dist);
memset(q,,sizeof q);
head=tail=dist[t]=;
q[++tail]=t;
while (head<tail)
for (int x=q[++head],i=fst[x];i;i=e[i].nxt)
if (e[i].cap==&&dist[e[i].y]==-)
dist[q[++tail]=e[i].y]=dist[x]+;
for (int i=;i<=n;i++)
if (dist[i]==-)
dist[i]=n;
}
int Augment(int &point){
int ex_Flow=Inf;
for (int i=t;i!=s;i=e[p[i]].x)
if (ex_Flow>=e[p[i]].cap-e[p[i]].flow)
ex_Flow=e[p[i]].cap-e[p[i]].flow,point=e[p[i]].x;
for (int i=t;i!=s;i=e[p[i]].x)
e[p[i]].flow+=ex_Flow,e[p[i]^].flow-=ex_Flow;
return ex_Flow;
}
int SAP(){
int x=s,y,MaxFlow=;
memset(num,,sizeof num);
for (int i=;i<=n;i++)
num[dist[i]]++,cur[i]=fst[i];
while (dist[s]<=n){
if (x==t){
MaxFlow+=Augment(x);
continue;
}
bool found=;
for (int i=cur[x];i!=&&!found;i=e[i].nxt)
if (dist[e[i].y]+==dist[x]&&e[i].cap>e[i].flow)
cur[x]=p[e[i].y]=i,x=e[i].y,found=;
if (found)
continue;
int d=n+;
for (int i=fst[x];i;i=e[i].nxt)
if (e[i].cap>e[i].flow)
d=min(d,dist[e[i].y]+);
if (!(--num[dist[x]]))
return MaxFlow;
num[dist[x]=d]++,cur[x]=fst[x];
if (x!=s)
x=e[p[x]].x;
}
return MaxFlow;
}
}g;
int n,m,a[N],b[N],sum=,mat[N][N];
int main(){
scanf("%d%d",&n,&m);
g.set(n+m+,n+m+,n+m+);
for (int i=;i<=n;i++)
scanf("%d",&a[i]),sum+=a[i],g.add(g.s,i,a[i],);
for (int i=;i<=m;i++)
scanf("%d",&b[i]),g.add(i+n,g.t,b[i],);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
g.add(i,j+n,,);
g.re_bfs();
int Flow=g.SAP();
puts(Flow<sum?"":"");
if (Flow<sum)
return ;
memset(mat,,sizeof mat);
for (int i=;i<=g.cnt;i++)
if (g.e[i].flag==&&g.e[i].cap==&&g.e[i].flow==){
int x=g.e[i].x,y=g.e[i].y-n;
mat[x][++mat[x][]]=y;
}
for (int i=;i<=n;i++)
sort(mat[i]+,mat[i]+mat[i][]+);
for (int i=;i<=n;puts(""),i++)
for (int j=;j<=mat[i][];j++)
printf("%d ",mat[i][j]);
return ;
}
网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流的更多相关文章
- 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)
[题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...
- hihoCoder 1393 网络流三·二分图多重匹配(Dinic求二分图最大多重匹配)
#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小H ...
- hiho 第117周 二分图多重匹配,网络流解决
描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含 ...
- HDU 5352——MZL's City——————【二分图多重匹配、拆点||网络流||费用流】
MZL's City Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- 网络流24(san)题题解汇总
开坑(烂尾预定 1.餐巾计划问题 题解 2.最小路径覆盖问题 题解 3.试题库问题 题解 4.[CTSC1999]家园 题解 5.骑士共存问题 题解 6.最长不下降子序列问题 题解 7.深海机器人问题 ...
- 【网络流24题】 No.5 圆桌问题 (多重匹配)
[题意] 假设有来自 n 个不同单位的代表参加一次国 际会议.每个单位的代表数分别为r i ni , = 1,2, .会议餐厅共有 m 张餐桌,每张餐桌可容纳 ci (i = 1,2, , m) 个 ...
- 查找最小的k个元素 【微软面试100题 第五题】
题目要求: 输入n个整数,输出其中最小的k个. 例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4. 参考资料:剑指offer第30题. 题目分析: 解法一: 用快排 ...
- [HIHO1393]网络流三·二分图多重匹配
题目链接:http://hihocoder.com/problemset/problem/1393 把项目到汇点的边权值都加起来,跑完最大流后看是否最大流=权值和.如果等于权值和说明所有项目都有足够的 ...
- POJ3189_Steady Cow Assignment(二分图多重匹配/网络流+二分构图)
解题报告 http://blog.csdn.net/juncoder/article/details/38340447 题目传送门 题意: B个猪圈,N头猪.每头猪对每一个猪圈有一个惬意值.要求安排这 ...
随机推荐
- WIN10下安装USB转串口驱动出现“文件的哈希值不在指定的目录”的解决办法
今天安装openJTAG驱动时出现“文件的哈希值不在指定的目录”,系统为WIN10专业版. 原因是驱动无数字签名,在WIN10中是不安全的驱动,所以显示哈希值不在范围内不能安装. 经查阅已经解决,发放 ...
- 完整版ffmpeg使用情况
protected void Page_Load(object sender, EventArgs e) { string filePath = @"D:/Prjects/MT147/exa ...
- dubbo服务使用spring-data-mongodb进行时间查询的bug记录
一.项目情况:spring-boot+mongodb+dubbo. 二.问题:调用dubbo服务并使用spring-data-mongodb的gte,lte时间段比较查询, @Reference(re ...
- emacs(考场+平时)配置方案
考场配置: ;;在配置后面会对语句逐一解释的 (global-set-key (kbd "C-z") 'undo) (global-set-key (kbd "RET&q ...
- vue学习起步:了解下
渐进式 有这么一句话,vue是渐进式框架. 抽取“渐进式框架”和“自底向上增量开发的设计”这两个概念是什么?中的解释: 渐进式代表的含义是:主张(主张指使用时的硬性要求)最少.来个对比就知道什么叫主张 ...
- mysql 原理 ~ 二阶段提交协议通说
一 简介: 今天是第二篇,讲解的是mysql的事务日志 二 具体 1 WAL技术(先写日志,再写磁盘) 2 binlog redolog 二阶段提交协议 目的 保持 redo log和binl ...
- jquery 学习(七) - 常用动态效果
<!--转载于 听说你的代码很6--><!--http://www.jq22.com/webqd2377--> CSS <style> #content #firs ...
- Maven私服
1.关于中央仓库注意事项地址: 目前来说: http://repo1.maven.org/maven2/是真正的 Maven 中央仓库的地址,该地址内置在Maven 的源码中,其他的都是镜像.索引: ...
- ROC,AUC,PR,AP介绍及python绘制
这里介绍一下如题所述的四个概念以及相应的使用python绘制曲线: 参考博客:http://kubicode.me/2016/09/19/Machine%20Learning/AUC-Calculat ...
- Redis消息通知(任务队列和发布订阅模式)
Redis学习笔记(十)消息通知(任务队列和发布订阅模式) 1. 任务队列 1.1 任务队列的特点 任务队列:顾名思义,就是“传递消息的队列”.与任务队列进行交互的实体有两类,一类是生产者(produ ...