[网络流24题-4]cogs729 圆桌聚餐
来源:互联网 发布:淘宝物流重量怎么填 编辑:程序博客网 时间:2024/06/07 01:09
我发现我的网络流真的建模很差。。。。这题2星的难度,我觉得我完全可以做下来,但是最终还是无法设计出一个显式的方案,或者说两个限制条件没有结合起来;最终看了hzwer神犇的题解才明白。
题目传送cogs729圆桌聚餐
首先他说有
首先我就想,如果是每个单位不同的人要坐不同的桌子 那么二分图匹配要用上了。。。。然而每个桌子都有一个容量,我把它想成是一个有下界的结点,再把他拆成一条边,然而这样又难以和二分图匹配联系起来。左右思之,还是去看了下题解,发现了很巧妙的办法:
建立超级源点s和超级汇点t,从s到每个单位建立一个单位所有人为容量的边,然后从每个桌子到汇点建一条容量为桌子容量的边,再把每个单位和每个桌子连容量为1的边。。。。我只觉得这样做很妙,首先它保证了每个单位每个人桌子不同,然后他也保证了每个桌子不超人。。。。要我自己去想,我可能还没到这种高度,真的建不出来这种模。
大家有没有固定的这样建模的技巧什么的。。。。有的话一定要告诉我qwq
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <queue>#include <map>using namespace std;const int inf=0x3f3f3f3f;const int maxn=275;const int maxm=155;int co[maxm];int des[maxn];int m,n;struct edge{ int to,cap,rev;};vector<edge> g[maxn+maxm];void addedge(int from,int to,int cap){ g[from].push_back((edge){to,cap,g[to].size()}); g[to].push_back((edge){from,0,g[from].size()-1});}int dis[maxn+maxm+2];bool bfs(int st,int ed){ memset(dis,inf,sizeof(dis)); int head=0; int tail=0; int q[maxn+maxm+2]; memset(q,0,sizeof(q)); q[head]=st; dis[st]=0; while(head<=tail) { int top=q[head]; head++; for(unsigned i=0;i<g[top].size();i++) { edge & e=g[top][i]; if(dis[e.to]==inf && e.cap>0) { dis[e.to]=dis[top]+1; tail++; q[tail]=e.to; } } } return dis[ed]!=inf;}int dfs(int v,int ed,int leftflow){ if(v==ed || leftflow==0) { return leftflow; } for(unsigned i=0;i<g[v].size();i++) { edge &e=g[v][i]; if(e.cap>0 && dis[e.to]==dis[v]+1) { int f; f=dfs(e.to,ed,min(e.cap,leftflow)); if(f>0) { e.cap-=f; g[e.to][e.rev].cap+=f; return f; } } } return 0;}int dinic(int st,int ed){ int ans=0; while(bfs(st,ed)) { int f; while((f=dfs(st,ed,inf))>0) { ans+=f; } } return ans;}int main(){ freopen("roundtable.in","r",stdin); freopen("roundtable.out","w",stdout); bool flag=true; int per=0; int tabp=0; scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) { scanf("%d",&co[i]); per+=co[i]; } for(int i=1;i<=n;i++) { scanf("%d",&des[i]); tabp+=des[i]; } if(tabp<per) { flag=false; } else { int s=0; int t=m+n+1; for(int i=1;i<=m;i++) { addedge(s,i,co[i]); } for(int i=1;i<=n;i++) { addedge(i+m,t,des[i]); } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { addedge(i,j+m,1); } } int ans=dinic(s,t); if(ans<per) { flag=false; } if(flag==false) { printf("0\n"); } else { printf("1\n"); vector<int > ans[maxm+1]; for(int i=1;i<=m;i++) { for(unsigned j=0;j<g[i].size();j++) { edge & e=g[i][j]; if(e.cap==0) { ans[i].push_back(e.to); } } } for(int i=1;i<=m;i++) { for(unsigned j=0;j<ans[i].size();j++) { printf("%d ",ans[i][j]-m); } printf("\n"); } } } return 0;}
0 0
- cogs729. [网络流24题] 圆桌聚餐
- [网络流24题-4]cogs729 圆桌聚餐
- cogs729 圆桌聚餐
- [网络流24题] 圆桌聚餐
- [网络流24题]圆桌聚餐
- 网络流24题 05圆桌聚餐
- 网络流24题 圆桌聚餐
- [网络流24题] 圆桌聚餐 最大流/路径输出
- [网络流24题] 05 圆桌聚餐(最大流判满流)
- COGS 729 [网络流24题] 圆桌聚餐
- Cogs 729. [网络流24题] 圆桌聚餐
- COGS 729. [网络流24题] 圆桌聚餐
- [Loj]#6004. 「网络流 24 题」圆桌聚餐
- 「网络流 24 题」圆桌聚餐
- 【网络流24题】圆桌聚餐(二分图)
- 「网络流 24 题」圆桌聚餐
- loj #6004. 「网络流 24 题」圆桌聚餐(最大流)
- loj6004「网络流 24 题」圆桌聚餐(最大流)
- C#抽象方法和抽象类
- HDU 2955 Robberies(01背包)
- C++ 多态机制实现
- 希尔排序
- 在linux下编译cpp文件出现错误
- [网络流24题-4]cogs729 圆桌聚餐
- 迷宫寻路问题——一阶谓词逻辑
- Android退出应用
- jQuery
- Caffe依赖包解析
- 死锁
- 数据结构之排序算法
- 提高篇十六讲项目1.1——创建整型数组改变数组元素的值,令所有的数据加倍,输出改变后的值。
- 微信公众号开发--简单总结