1. 程式人生 > >LiberOJ 6004. 「網絡流 24 題」圓桌聚餐 網絡流版子題

LiberOJ 6004. 「網絡流 24 題」圓桌聚餐 網絡流版子題

單位 技術分享 希望 cos 測試數據 ott pre max line

#6004. 「網絡流 24 題」圓桌聚餐

內存限制:256 MiB時間限制:5000 ms標準輸入輸出 題目類型:傳統評測方式:Special Judge 上傳者: 匿名 提交提交記錄統計討論測試數據

題目描述

假設有來自 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 2701m150,1n270

題目鏈接: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 題」圓桌聚餐 網絡流版子題