poj3189 Steady Cow Assignment(枚举+多重匹配)
2016-07-02 22:57
381 查看
有n头牛和b个棚,每个棚有容量上限。每头牛对每个棚有个喜欢程度,现在给牛分配住棚且棚中牛的数目不能超过该棚的上限。
先输入n,b。然后n行,每行有b个数字x[j],表示该头牛对棚子x[j]的喜欢程度是j。
现在求一种分配方法使得任意两头牛对所在棚的满意程度的差值最小,输出最小差值。
方法:枚举棚子满意度的上下限[low, high],然后做多重二分图匹配。
先输入n,b。然后n行,每行有b个数字x[j],表示该头牛对棚子x[j]的喜欢程度是j。
现在求一种分配方法使得任意两头牛对所在棚的满意程度的差值最小,输出最小差值。
方法:枚举棚子满意度的上下限[low, high],然后做多重二分图匹配。
const int maxn = 1010; const int maxm = 21; int n, b; int like[maxn][maxm]; int linker[maxm][maxn]; int top[maxm]; int num[maxm]; bool mark[maxm]; int low, high; bool dfs(int u) { for (int v = 1;v <= b;++v) { if (!mark[v] && low <= like[u][v] && like[u][v] <= high) { mark[v] = true; if (top[v] < num[v]) { linker[v][top[v]++] = u; return true; } for (int i = 0;i < top[v];++i) { if (dfs(linker[v][i])) { linker[v][i] = u; return true; } } } } return false; } bool hungary() { memset(top, 0,sizeof top); for (int i = 1;i <= n;++i) { memset(mark, false,sizeof mark); if (!dfs(i)) return false; } return true; } void solve() { low = high = 1; int ans = b; while(low <= high && high <= b) { if (hungary()) { ans = min(ans, high - low + 1); low++; // bug; }else high++; } cout << ans << endl; } int main(int argc, const char * argv[]) { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); // clock_t _ = clock(); while(~scanf("%d%d", &n, &b)) { int u, v; for (int i = 1;i <= n;++i) { for (int j = 1;j <= b;++j) { scanf("%d", &v); like[i][v] = j; } } for (int i = 1;i <= b;++i) scanf("%d", &num[i]); solve(); } // printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC); return 0; }
相关文章推荐
- 二分图匹配 ( 多重匹配&&Hungarian)——Escape ( HDU 3605 )
- HDU 3605 Escape 【二分匹配之多重匹配】
- 234. Palindrome Linked List(重要)
- ThinkPHP3.2.3 勾选子级自动选择父级
- EM算法简单介绍
- MAC下基于JAVA和Tomcat的微信二次开发环境配置
- 最短路程
- win10激活的帖子
- python中%r和%s的区别
- Linux下设置memcached访问IP
- 库克访华开座谈会 中国开发者逐渐受重视
- MyBatis的XML配置文件(一)
- cocos2dx打包apk
- 2016-7-2 杂感
- Hyper-V虚拟机不能上网问题的解决方法
- delegate的使用
- 理发
- 网页如何有效调用exe
- 开启MyBatis(三)工作原理
- WebService—WSDL详解