LiberOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题
Posted GeekZRF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LiberOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题相关的知识,希望对你有一定的参考价值。
#6004. 「网络流 24 题」圆桌聚餐
题目描述
假设有来自 n nn 个不同单位的代表参加一次国际会议。每个单位的代表数分别为 ri r_ir?i??。会议餐厅共有 m mm 张餐桌,每张餐桌可容纳 ci c_ic?i?? 个代表就餐。
为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。
试设计一个算法,给出满足要求的代表就餐方案。
输入格式
文件第 1 11 行有 2 22 个正整数 m mm 和 n nn,m mm 表示单位数,n nn 表示餐桌数。
文件第 2 22 行有 m mm 个正整数,分别表示每个单位的代表数。
文件第 3 33 行有 n nn 个正整数,分别表示每个餐桌的容量。
输出格式
如果问题有解,在文件第 1 11 行输出 1 11,否则输出 0 00。
接下来的 m mm 行给出每个单位代表的就餐桌号。如果有多个满足要求的方案,只要输出一个方案。
样例
样例输入
4 5
4 5 3 5
3 5 2 6 4
样例输出
1
1 2 4 5
1 2 3 4 5
2 4 5
1 2 3 4 5
数据范围与提示
1≤m≤150,1≤n≤270 1 \leq m \leq 150, 1 \leq n \leq 2701≤m≤150,1≤n≤270
题目链接:https://loj.ac/problem/6004
思路:最大流板子题
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<set> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; typedef long long ll; typedef pair<int,int> P; #define PI acos(-1.0) const int maxn=500,maxm=1e5+100,inf=0x3f3f3f3f,mod=1e9+7; const ll INF=1e18+7; struct edge { int from,to,cap,flow; }; vector<edge>es; vector<int>G[maxn]; bool vis[maxn]; int dist[maxn]; int iter[maxn]; void init(int n) { for(int i=0; i<=n+10; i++) G[i].clear(); es.clear(); } void addedge(int from,int to,int cap) { es.push_back((edge) { from,to,cap,0 }); es.push_back((edge) { to,from,0,0 }); int x=es.size(); G[from].push_back(x-2); G[to].push_back(x-1); } bool BFS(int s,int t) { memset(vis,0,sizeof(vis)); queue <int> Q; vis[s]=1; dist[s]=0; Q.push(s); while(!Q.empty()) { int u=Q.front(); Q.pop(); for (int i=0; i<G[u].size(); i++) { edge &e=es[G[u][i]]; if (!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; dist[e.to]=dist[u]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int u,int t,int f) { if(u==t||f==0) return f; int flow=0,d; for(int &i=iter[u]; i<G[u].size(); i++) { edge &e=es[G[u][i]]; if(dist[u]+1==dist[e.to]&&(d=DFS(e.to,t,min(f,e.cap-e.flow)))>0) { e.flow+=d; es[G[u][i]^1].flow-=d; flow+=d; f-=d; if (f==0) break; } } return flow; } int Maxflow(int s,int t) { int flow=0; while(BFS(s,t)) { memset(iter,0,sizeof(iter)); int d=0; while(d=DFS(s,t,inf)) flow+=d; } return flow; } int a[maxn],b[maxn]; int main() { int n,m; scanf("%d%d",&n,&m); int s=0,t=n+m+1; init(n+m+10); int sum=0; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) addedge(i,j+n,1); } for(int i=1; i<=n; i++) { scanf("%d",&a[i]); sum+=a[i]; addedge(s,i,a[i]); } for(int i=1; i<=m; i++) { scanf("%d",&b[i]); addedge(i+n,t,b[i]); } if(Maxflow(s,t)<sum) printf("0\n"); else { printf("1\n"); for(int i=0; i<n*m*2; i+=2) { if(es[i].flow>0) printf("%d ",es[i].to-n); if(es[i].to-n==m) printf("\n"); } } return 0; }
以上是关于LiberOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题的主要内容,如果未能解决你的问题,请参考以下文章
LiberOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题
LiberOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖
LiberOJ #6000. 「网络流 24 题」搭配飞行员 最大匹配