题意:

来自n个不同国家的代表开会,每个国家代表数为ci 会场有m张圆桌,每张桌子可容纳mi人 不希望有同一个国家的代表在同一张桌子上就餐 设计一个合法方案

(n,m<=300)

思路:最大流,保存原边上限,与残余网络比较是否有所变动即可。

【问题分析】

二分图多重匹配问题,可以用最大流解决。

【建模方法】

建立二分图,每个单位为X集合中的顶点,每个餐桌为Y集合中的顶点,增设附加源S和汇T。

1、从S向每个Xi顶点连接一条容量为该单位人数的有向边。

2、从每个Yi顶点向T连接一条容量为该餐桌容量的有向边。

3、X集合中每个顶点向Y集合中每个顶点连接一条容量为1的有向边。

求网络最大流,如果最大流量等于所有单位人数之和,则存在解,否则无解。对于每个单位,从X集合对应点出发的所有满流边指向的Y集合的顶点就是该单位人员的安排情况(一个可行解)。

【建模分析】

对于一个二分图,每个顶点可以有多个匹配顶点,称这类问题为二分图多重匹配问题。X,Y集合之间的边容量全部是1,保证两个点只能匹配一次(一个餐桌上只能有一个单位的一个人),源汇的连边限

制了每个点匹配的个数。求出网络最大流,如果流量等于X集合所有点与S边容量之和,那么则说明X集合每个点都有完备的多重匹配。

【问题另解】

贪心,更好的方法其实是贪心。首先把所有单位和餐桌按人数从大到小排序,一种适当的贪心策略就是对于每个单位,所有人每次尽量去剩余容量较大的餐桌就坐。按照这种贪心策略,如果某时发现有人

已经无法就坐,则无解。具体方法为用线段树维护餐桌的剩余容量,按人数从多到少安排每个单位的人员,每次安排就是把容量餐桌前k大的餐桌人数减1(k为该单位人数)。为保证线段树前k位时刻为前

k大,要维护第k与第k+1,k+2,...人数与第k相等的位置,减少第k大时要减少尽量靠后的,这样才能保证单调。

UPD(19.10.28):显然这个线段树维护的贪心做法只有在判断是否有解的时候有用,因为光输出方案的复杂度就比它大

其次这个前k大变动的时刻真的能维护?理解不能……

UPD(19.10.29):听说splay可以做,要支持区间-1和把前k大的区间抠出来,等其他题目结束以后写一下,感觉细节有点多

 var head,vet,next,len,dis,gap,ob,save,fan:array[..]of longint;
a,b,q:array[..]of longint;
num:array[..,..]of longint;
n,m,i,j,src,source,tot,s,sum:longint; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot; inc(tot);
next[tot]:=head[b];
vet[tot]:=a;
len[tot]:=;
head[b]:=tot;
end; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function dfs(u,aug:longint):longint;
var e,v,t,val,flow:longint;
begin
if u=src then exit(aug);
e:=head[u]; val:=s-; flow:=;
while e<> do
begin
v:=vet[e];
if len[e]> then
begin
if dis[u]=dis[v]+ then
begin
t:=dfs(v,min(len[e],aug-flow));
len[e]:=len[e]-t;
len[fan[e]]:=len[fan[e]]+t;
flow:=flow+t;
if dis[source]>=s then exit(flow);
if aug=flow then break;
end;
val:=min(val,dis[v]);
end;
e:=next[e];
end;
if flow= then
begin
dec(gap[dis[u]]);
if gap[dis[u]]= then dis[source]:=s;
dis[u]:=val+;
inc(gap[dis[u]]);
end;
exit(flow);
end; function maxflow:longint;
var ans:longint;
begin
fillchar(gap,sizeof(gap),);
fillchar(dis,sizeof(dis),);
gap[]:=s; ans:=;
while dis[source]<s do ans:=ans+dfs(source,maxlongint);
exit(ans);
end; procedure print;
var i,j,s:longint;
begin
writeln();
for i:= to n do
begin
s:=;
for j:= to m do
if len[num[i,j]]<>save[num[i,j]] then begin inc(s); q[s]:=j; end;
for j:= to s- do write(q[j],' ');
write(q[s]);
writeln;
end;
end; begin
assign(input,'poweroj1740.in'); reset(input);
assign(output,'poweroj1740.out'); rewrite(output);
readln(n,m);
for i:= to do
if i mod = then fan[i]:=i+
else fan[i]:=i-;
for i:= to n do begin read(a[i]); sum:=sum+a[i]; end;
for i:= to m do read(b[i]);
s:=n+m+; source:=n+m+; src:=n+m+;
for i:= to n do
for j:= to m do
begin
num[i,j]:=tot+; add(i,j+n,);
end;
for i:= to tot do save[i]:=len[i];
for i:= to n do add(source,i,a[i]);
for i:= to m do add(i+n,src,b[i]);
if maxflow<sum then writeln()
else print;
close(input);
close(output);
end.

【PowerOJ1740&网络流24题 圆桌聚餐】(最大流)的更多相关文章

  1. Cogs 729. [网络流24题] 圆桌聚餐

    [网络流24题] 圆桌聚餐 ★★ 输入文件:roundtable.in 输出文件:roundtable.out 评测插件 时间限制:1 s 内存限制:128 MB «问题描述: 假设有来自m 个不同单 ...

  2. COGS729. [网络流24题] 圆桌聚餐

    «问题描述:假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri(i=1,2,3...m), .会议餐厅共有n张餐桌,每张餐桌可容纳c i(i=1,2...n) 个代表就餐.为了 ...

  3. [洛谷P3254] [网络流24题] 圆桌游戏

    Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...

  4. 网络流24题——圆桌问题 luogu 3254

    题目传送门:这里 这是网络流24题里最简单的一道,我们从这里开始 虽然是网络流24题之一,但可以不用网络流... 本题采用贪心即可 有一个很显然的思想:在分配每一组时,我们都应当优先分配给当前可容纳人 ...

  5. 【PowerOJ1740&网络流24题】圆桌聚餐(最大流)

    题意: 来自n个不同国家的代表开会,每个国家代表数为ci 会场有m张圆桌,每张桌子可容纳mi人 不希望有同一个国家的代表在同一张桌子上就餐 设计一个合法方案 (n,m<=300) 思路:最大流, ...

  6. Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)

    Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...

  7. LibreOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题

    #6004. 「网络流 24 题」圆桌聚餐 内存限制:256 MiB时间限制:5000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数 ...

  8. 【最大流/二分图匹配】【网络流24题】【P3254】 圆桌问题

    Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...

  9. 【网络流24题】最长k可重线段集(费用流)

    [网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...

随机推荐

  1. 获得图片颜色---摘自php手册

    Example #1 imagecolorsforindex() 例子 ;$color_index = imagecolorat($im, $start_x, $start_y); // 使其可读$c ...

  2. Kafka/Metaq设计思想学习笔记 转

    转载自: http://my.oschina.net/geecoodeer/blog/194829 本文没有特意区分它们之间的区别,仅仅是列出其中笔者认为好的设计思想,供后续设计参考. 目前笔者并没有 ...

  3. 50 道 Java 线程面试题(转载自牛客网)

    下面是 Java 线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理 ...

  4. Java web项目引用java项目,类型找不到

    Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...

  5. oracle 左边填充函数使用

    左边填充 select lpad('abcde',10,'0') from dual; ==>00000abcde select lpad('abcde',10,'x') from dual;= ...

  6. UIScroView 3倍的contentSize,左右Scroll时,懒惰加载View

    UIScroView 3倍的contentSize,左右Scroll时,懒惰添加左右的View 用途:分段加载数据 定义枚举: typedefenum { ViewPositionLeft = , V ...

  7. Openstack Neutron L2 Population

    Why do we need it, whatever it is? VM unicast, multicast and broadcast traffic flow is detailed in m ...

  8. mysql 的 infobright 数据库的 mediumblob 显示不了数据

    需要修改mysql的配置文件: /var/www/html/phpmyadmin/config.inc.php 增加: $cfg['ProtectBinary'] = FALSE; 即可

  9. PHP导出数据到excel的方法

    很简单,看内容,不多说了: <?php //设置标题 $header[] = "ID"; $header[] = "订单"; $header[] = &q ...

  10. java 线程数据同步

    java 线程数据同步 由买票实例 //java线程实例 //线程数据同步 //卖票问题 //避免重复卖票 //线程 class xc1 implements Runnable{ //定义为静态,可以 ...