[网络流24题] 圆桌聚餐
2017-03-12 17:27
281 查看
729. [网络流24题] 圆桌聚餐
★★ 输入文件:roundtable.in
输出文件:
roundtable.out评测插件
时间限制:1 s 内存限制:128 MB
«问题描述:
假设有来自m 个不同单位的代表参加一次国际会议。每个单位的代表数分别为
ri(i=1,2,3...m), 。会议餐厅共有n张餐桌,每张餐桌可容纳c i(i=1,2...n) 个代表就餐。
为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法,
给出满足要求的代表就餐方案。
«编程任务:
对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。
«数据输入:
由文件roundtable.in提供输入数据。文件第1行有2 个正整数m和n,m表示单位数,n表
示餐桌数,1<=m<=150, 1<=n<=270。文件第2 行有m个正整数,分别表示每个单位的代表
数。文件第3 行有n个正整数,分别表示每个餐桌的容量。
«结果输出:
程序运行结束时,将代表就餐方案输出到文件roundtable.out中。如果问题有解,在文件第
1 行输出1,否则输出0。接下来的m行给出每个单位代表的就餐桌号。如果有多个满足要
求的方案,只要输出1 个方案。
输入文件示例 输出文件示例
roundtable.in
4 5 4 5 3 5 3 5 2 6 4roundtable.out
1 1 2 4 5 1 2 3 4 5 2 4 5 1 2 3 4 5[b]分析: [/b]
比较裸的二分图。若满流,则有解;否则,无解。
方案输出:对于每一组,把满流的边的右端点依次输出
显示代码纯文本
#include<cstdio> #include<cstring> #include<algorithm> #define setfile(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout); using namespace std; const int N=1e4+5; const int inf=2e9; struct edge{int v,cap,next;}e[N*10];int tot=1,head[N]; int n,m,S,T,ans,total,dis[N],q[N*10]; void add(int x,int y,int z){ e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot; } bool bfs(){ memset(dis,-1,sizeof dis); unsigned short h=0,t=1;q[t]=S;dis[S]=0; while(h!=t){ int x=q[++h]; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==-1){ dis[e[i].v]=dis[x]+1; if(e[i].v==T) return 1; q[++t]=e[i].v; } } } return 0; } int dfs(int x,int f){ if(x==T) return f; int used=0,t; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]==dis[x]+1){ t=dfs(e[i].v,min(e[i].cap,f)); e[i].cap-=t;e[i^1].cap+=t; used+=t;f-=t; if(!f) return used; } } if(!used) dis[x]=-1; return used; } inline void out_ans(){ puts("1"); for(int i=1;i<=n;i++){ for(int j=head[i];j;j=e[j].next){ if(!e[j].cap){ printf("%d ",e[j].v-n); } } putchar('\n'); } } inline void dinic(){ while(bfs()) ans+=dfs(S,inf); if(ans==total) out_ans(); else puts("0"); } inline void init(){ scanf("%d%d",&n,&m);S=0,T=n+m+1; for(int i=1,x;i<=n;i++) scanf("%d",&x),total+=x,add(S,i,x); for(int i=1,x;i<=m;i++) scanf("%d",&x),add(i+n,T,x); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ add(i,j+n,1); } } } int main(){ setfile(roundtable) init(); dinic(); return 0; }
相关文章推荐
- [Loj]#6004. 「网络流 24 题」圆桌聚餐
- loj #6004. 「网络流 24 题」圆桌聚餐(最大流)
- 「网络流 24 题」圆桌聚餐
- 【网络流24题】圆桌聚餐(二分图)
- COGS 729. [网络流24题] 圆桌聚餐
- 【loj】#6004. 「网络流 24 题」圆桌聚餐(二分图匹配)
- Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)
- 网络流24题 圆桌聚餐
- loj6004「网络流 24 题」圆桌聚餐(最大流)
- loj6004「网络流 24 题」圆桌聚餐
- Cogs 729. [网络流24题] 圆桌聚餐
- cogs 729. [网络流24题] 圆桌聚餐
- LOJ6004 「网络流 24 题 - 5」圆桌聚餐 最大流
- 【网络流24题】圆桌聚餐(最大流)
- 【PowerOJ1740&网络流24题 圆桌聚餐】(最大流)
- [网络流24题-4]cogs729 圆桌聚餐
- [网络流24题]圆桌聚餐
- cogs729. [网络流24题] 圆桌聚餐
- [网络流24题] 圆桌聚餐
- [网络流24题] 圆桌聚餐 最大流/路径输出