POJ 2112:Optimal Milking
来源:互联网 发布:淘宝机器人自动回复 编辑:程序博客网 时间:2024/06/15 19:40
题目链接:http://poj.org/problem?id=2112
题目翻译:有K个挤奶机,每个挤奶机可以容纳M头牛,总共有C头牛要挤奶,问C头牛中怎样分配可以使
走最远距离的那头牛走的距离尽量小,求出这个最远距离的最小值。
输入:K,M,C。 然后K+C的方阵表示各个物体间距离。
解题思路:网络流+二分。
先Flody求每个奶牛到每个挤奶机的最短距离。
每个奶牛只能去一个挤奶机器。
建立超级源点S,超级汇点D,由超级源点到每一头奶牛建立一条边,其容量就是1,代表1头牛,
由每台机器向超级汇点引一条边,其容量就是M,然后采用二分的方法求解答案,我们假设maxdist
是个挺大的数吧,然后如果dist[i][j] 也就是第i头牛到第j个挤奶机器的最短路小于maxdist,则我们
可以建一条边由第i头牛到第j头牛,其容量为1,然后我们求这个图的最大流,如果我们发现当前最
大流是C,则说明所有的牛都已经有相应的挤奶机器挤奶,我们可以缩小这个maxdist看看答案范围
能够缩小,如果最大流小于C则,我们就要扩大maxdist,来找符合题目的距离。
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;int Map[240][240],head[240],level[240],vis[240],cap[240][240];int K,C,M,S,D,maxdist,edgeNumber,minFlow,minFlowNode,maxFlow; ///K台挤奶机,C头奶牛,每个机器可以容纳M头奶牛void Flody() { for(int k = 1; k <= K+C; k++) for(int i = 1; i <= K+C; i++) for(int j = 1; j <= K+C; j++) { if(Map[i][k] + Map[k][j] < Map[i][j]) Map[i][j] = Map[i][k] + Map[k][j]; }}bool bfs() { queue<int>qu; memset(level,-1,sizeof(level)); level[S] = 0; qu.push(S); while(!qu.empty()) { int u = qu.front(); qu.pop(); for(int i = 0; i <= K+C+1; i++) { if(level[i]==-1 && cap[u][i] > 0) { level[i] = level[u] + 1; if(i == D) return true; qu.push(i); } } } return false;}void dfs() { int u,v,cur,i; deque<int>qu; memset(vis,0,sizeof(vis)); vis[S] = 1; qu.push_back(S); while(!qu.empty()) { cur = qu.back(); if(cur == D){ minFlow = INF+1; minFlowNode = S; for(i = 1; i < qu.size(); i++) { u = qu[i-1]; v = qu[i]; if(cap[u][v]>0 && minFlow>cap[u][v]) { minFlow = cap[u][v]; minFlowNode = u; } } maxFlow += minFlow; for(i = 1; i < qu.size(); i++) { u = qu[i-1]; v = qu[i]; cap[u][v] -= minFlow; cap[v][u] += minFlow; } while(!qu.empty() && qu.back() != minFlowNode) { vis[qu.back()] = 0; qu.pop_back(); } }else { for(i = 1; i <= K+C+1; i++) { if(cap[cur][i]>0 && level[i] == level[cur]+1 && vis[i]==0) { vis[i] = 1; qu.push_back(i); break; } } if(i > K+C+1) qu.pop_back(); } }}///求最大流void dinic() { maxFlow = 0; while(bfs()) { dfs(); }}///建图void buildGraph(int top){ memset(cap,0,sizeof(cap)); for(int i = K+1; i <= K+C; i++) cap[S][i] = 1; for(int i = 1; i <= K; i++) cap[i][D] = M; for(int i = K+1; i <= K+C; i++) for(int j = 1; j <= K; j++) { if(Map[i][j]<=top) cap[i][j] = 1; }}void solve() { int ans = 1,low = 1,high = maxdist; while(low <= high) { int mid = (low+high)/2; buildGraph(mid); dinic(); if(maxFlow == C) { ans = mid; high = mid - 1; }else { low = mid + 1; } } printf("%d\n",ans);}int main(){ while(~scanf("%d%d%d",&K,&C,&M)) { maxdist = 0; for(int i = 1; i <= K+C; i++) for(int j = 1; j <= K+C; j++){ scanf("%d",&Map[i][j]); maxdist += Map[i][j]; if(Map[i][j] == 0 && i != j) ///二者之间没有道路 Map[i][j] = INF; } Flody(); S = 0; D = K+C+1; solve(); } return 0;}
阅读全文
0 0
- POJ 2112 Optimal Milking
- POJ 2112 OPtimal Milking
- POJ 2112 Optimal Milking
- poj 2112 Optimal Milking
- POJ-2112-Optimal Milking
- poj 2112 Optimal Milking
- poj 2112 Optimal Milking
- poj-2112-Optimal Milking
- POJ 2112 Optimal Milking
- POJ 2112 Optimal Milking
- POJ 2112 Optimal Milking
- POJ 2112:Optimal Milking
- poj 2112 Optimal Milking
- [poj 2112]Optimal Milking
- 【Poj 2112】 Optimal Milking
- POJ-2112 Optimal Milking
- POJ 2112 Optimal Milking
- POJ 2112:Optimal Milking
- HDU6074 Phone Call(LCA+并查集)
- git命令--本地分支合并,上传,下拉
- Java IO -- 序列化
- keytool命令行创建Android安卓 keystore签名
- python解析URL中的域名
- POJ 2112:Optimal Milking
- H5性能测试入门及优化建议
- Service(二)使用Messenger
- 如何理解接口这个抽象的概念?
- jQuery——事件
- 关于端口聚合或端口聚合称呼的误区
- kali源代码简单说明
- HashMap-数组+链表集合
- 初识MVVM