分配问题[网络流24题之18]
2016-05-24 13:27
405 查看
问题描述:
有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为 cij 。试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。编程任务:
对于给定的 n 件工作和 n 个人,计算最优分配方案和最差分配方案。数据输入:
第 1 行有 1 个正整数 n,表示有 n 件工作要分配给 n 个人做。接下来的 n 行中,每行有 n 个整数 cij , 1≤i≤n , 1≤j≤n ,表示第 i 个人做第 j 件工作产生的效益为 cij 。结果输出:
输出共两行,第 1 行为最小总效益,第 2 行为最大总效益输入文件示例:
52 2 2 1 2
2 3 1 2 4
2 0 1 1 1
2 3 4 3 3
3 2 1 2 1
输出文件示例:
514
分析:
这一道裸地最小费用最大流问题,基本思路是像寻找最短路径一样每次寻找最小的花费,每寻找到一条就做一个调整,直到不存在路径为止;最大流就是直接把所有边权全部取负再进行以上操作即可。代码:
#include <cstring> #include <cstdio> #include <algorithm> #include <queue> using namespace std; const int inf = 0x3f3f3f3f; int n,m; int head[147],nxt[11447],to[11447],wei[11447],cost[11447],tot=1; queue<int >que; int dis[147],pre[147],pres[147]; bool vis[147]; int used; void add(int,int,int); bool bfs(); void dinic(); int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) add(145,i,0); for(int i=1;i<=n;++i) add(i+n,146,0); for(int i=1,a;i<=n;++i) for(int j=1;j<=n;++j){ scanf("%d",&a); add(i,j+n,a); } used = 0; while(bfs()) dinic(); printf("%d\n",used); for(int i=2;i<tot;i+=2){ wei[i] += wei[i^1]; wei[i^1] = 0; cost[i] = -cost[i]; cost[i^1] = -cost[i^1]; } used = 0; while(bfs()) dinic(); printf("%d",-used); return 0; } void add(int from,int tp,int spend){ ++tot;nxt[tot]=head[from];head[from]=tot;to[tot]=tp;wei[tot]=1;cost[tot]=spend; ++tot;nxt[tot]=head[tp];head[tp]=tot;to[tot]=from;wei[tot]=0;cost[tot]=-spend; } bool bfs(){ memset(dis,0x3f,sizeof dis); memset(vis,false,sizeof vis); dis[145] = 0; que.push(145); int now; do{ now = que.front(); vis[now] = false; que.pop(); for(int i=head[now];i;i=nxt[i]) if(dis[to[i]]>dis[now]+cost[i] && wei[i]){ dis[to[i]] = dis[now]+cost[i]; pre[to[i]] = now; pres[to[i]] = i; if(!vis[to[i]]){ que.push(to[i]); vis[to[i]] = true; } } }while(!que.empty()); return dis[146]!=inf; } void dinic(){ int now = 146; used += dis[146]; while(now != 145){ --wei[pres[now]]; ++wei[pres[now]^1]; now = pre[now]; } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性