【网络流24题】 圆桌问题 二分图多重匹配

假设有来自n 个不同单位的代表参加一次国际会议。每个单位的代表数分别为 ri,i=1,2,...,n 。会议餐厅共有m张餐桌,每张餐桌可容纳ci(i=1,2, ,m) 个代表就餐。 为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐。试设计一个算法, 给出满足要求的代表就餐方案。 编程任务: 对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案。
由文件input.txt提供输入数据。文件第1行有2 个正整数m和n,m表示单位数,n表 示餐桌数,1<=m<=150, 1<=n<=270。文件第2 行有m个正整数,分别表示每个单位的代表 数。文件第3 行有n个正整数,分别表示每个餐桌的容量。
程序运行结束时,将代表就餐方案输出到文件output.txt 中。如果问题有解,在文件第 1 行输出1,否则输出0。接下来的m行给出每个单位代表的就餐桌号。如果有多个满足要 求的方案,只要输出1 个方案
Sample Input
4 5 4 5 3 5 3 5 2 6 4
Sample Output
1 1 2 4 5 1 2 3 4 5 2 4 5 1 2 3 4 5
 
题解:
(S,每个代表团i,ri) (每一张餐桌i,T,ci) (每一个代表团i,每一个餐桌j,1).
 1 #include<iostream> 
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int N=605,INF=1999999999;
 7 int gi(){
 8     int str=0;char ch=getchar();
 9     while(ch>'9'||ch<'0')ch=getchar();
10     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
11     return str;
12 }
13 int n,m,S=0,T,num=1,head[N],sum1=0,sum2=0;
14 struct Lin{
15     int next,to,dis;
16 }a[N*N];
17 void init(int x,int y,int z){
18     a[++num].next=head[x];
19     a[num].to=y;
20     a[num].dis=z;
21     head[x]=num;
22     a[++num].next=head[y];
23     a[num].to=x;
24     a[num].dis=0;
25     head[y]=num;
26 }
27 int q[N],dep[N];
28 bool bfs()
29 {
30     memset(dep,0,sizeof(dep));
31     q[1]=S;dep[S]=1;int t=0,sum=1,x,u;
32     while(t!=sum)
33     {
34         x=q[++t];
35         for(int i=head[x];i;i=a[i].next){
36             u=a[i].to;
37             if(dep[u] || a[i].dis<=0)continue;
38             dep[u]=dep[x]+1;q[++sum]=u;
39         }
40     }
41     return dep[T];
42 }
43 int dfs(int x,int flow)
44 {
45     if(x==T || !flow)return flow;
46     int tmp,sum=0,u;
47     for(int i=head[x];i;i=a[i].next){
48         u=a[i].to;
49         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
50         tmp=dfs(u,min(flow,a[i].dis));
51         a[i].dis-=tmp;a[i^1].dis+=tmp;
52         sum+=tmp;flow-=tmp;
53     }
54     return sum;
55 }
56 int main()
57 {
58     int x;
59     n=gi();m=gi();
60     T=n+m+1;
61     for(int i=1;i<=n;i++){
62         x=gi();init(S,i,x);sum1+=x;
63     }
64     for(int i=1;i<=m;i++){
65         x=gi();init(i+n,T,x);sum2+=x;
66     }
67     if(sum1>sum2){
68         printf("0");
69         return 0;
70     }
71     for(int i=1;i<=n;i++)
72     for(int j=n+1;j<=n+m;j++)init(i,j,1);
73     int tot=0,tmp;
74     while(bfs()){
75         tmp=dfs(S,INF);
76         while(tmp)tot+=tmp,tmp=dfs(S,INF);
77     }
78     if(tot<sum1){
79         printf("0");
80         return 0;
81     }else printf("1\n");
82     for(int i=1;i<=n;i++){
83         for(int k=head[i];k;k=a[k].next){
84             if(a[k].to && a[k].dis==0)printf("%d ",a[k].to-n);
85         }
86         printf("\n");
87     }
88     return 0;
89 }

 

posted @ 2017-05-18 12:57  PIPIBoss  阅读(266)  评论(0编辑  收藏  举报