网络流24题——圆桌问题

来源:互联网 发布:有人招聘网络写手吗? 编辑:程序博客网 时间:2024/04/30 03:20

假设有来自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 个方案。


样例输入

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


唔,感觉没什么难的啊,就是很简单的搞定了。
就是很简单的二分图多重匹配的问题。
(我才知道,原来这个是多重匹配而不是匹配的变式)
唔,注意这个:
- 如果最大流量等于所有单位人数之和,则存在解,否则无解

#include<cstdio>  #include<vector>  #include<queue>  #include<cstring>  #define INF 1e8using namespace std;const int maxn=500;  struct Edge{int from,to,cap,flow;};  vector<Edge>edges;  vector<int>G[maxn];  int s,t,d[maxn],cur[maxn];  int a[maxn],b[maxn]; bool vis[maxn];void AddEdge(int from,int to,int cap){      edges.push_back((Edge){from,to,cap,0});      edges.push_back((Edge){to,from,0,0});      int sz=edges.size();      G[from].push_back(sz-2);      G[to].push_back(sz-1);  }  void Build(int n,int m){      s=0,t=n+m+1;      for(int i=1;i<=n;i++){          AddEdge(s,i,a[i]);          for(int j=1;j<=m;j++)              AddEdge(i,j+n,1);      }      for(int i=1;i<=m;i++)          AddEdge(i+n,t,b[i]);  }  bool BFS(){      memset(vis,false,sizeof(vis));      queue<int>Q;Q.push(s);      d[s]=0;vis[s]=true;    while(!Q.empty()){          int u=Q.front();Q.pop();          for(int i=0;i<G[u].size();i++){              Edge& e=edges[G[u][i]];              if(!vis[e.to] && e.cap>e.flow){                  vis[e.to]=true;                  d[e.to]=d[u]+1;                  Q.push(e.to);              }          }      }      return vis[t];  }  int DFS(int u,int a){      if(u==t || a==0) return a;      int f,flow=0;      for(int& i=cur[u];i<G[u].size();i++){          Edge& e=edges[G[u][i]];          if(d[e.to]==d[u]+1 && (f=DFS(e.to,min(a,e.cap-e.flow)))>0){              e.flow+=f;              edges[G[u][i]^1].flow-=f;              flow+=f;              a-=f;              if(a==0)break;          }      }      return flow;  }  int dinic(){      int flow=0;      while(BFS()){          memset(cur,0,sizeof(cur));          flow+=DFS(s,INF);      }      return flow;  }  void Print(int n,int m){      for(int u=1;u<=n;u++){          for(int i=0;i<G[u].size();i++){              Edge& e=edges[G[u][i]];              if(e.flow==1 && e.to!=t)                  printf("%d ",e.to-n);          }        printf("\n");    }  }  int main(){      int n,m;      scanf("%d%d",&n,&m);      int sum=0;      for(int i=1;i<=n;i++){          scanf("%d",&a[i]);          sum+=a[i];      }      for(int i=1;i<=m;i++)          scanf("%d",&b[i]);      Build(n,m);      int flow=dinic();      if(flow>=sum){          printf("1\n");        Print(n,m);      }      else  printf("0\n");     return 0;  }  
0 0
原创粉丝点击