POJ2112 Optimal Milking(最大流+二分答案)
来源:互联网 发布:象棋网络直播 编辑:程序博客网 时间:2024/06/08 16:55
题意: 有K个挤奶器,和C头牛,让你求所有牛到挤奶器的最近距离的最远是多大。
题解: 由于挤奶器的不唯一,所以我们不能直接的求,然后对于多源点的求解问题,我们应该很直观的会有一个想法,那就是最大流能不能搞?
事实证明这个方法是可行的,我们用folyd预处理求出两点间的最短距离,然后二分距离,如果当前距离是我们构成的流的最大值等于牛的个数那么证明当前距离是可行的方案,然后继续二分直至结束。
至于怎么构图呢?我们可以设立一个超级源点和超级汇点,然后把所有的挤奶器和源点建立一条容量为M的边,所有挤奶器和牛建立一天容量为1的边,所有牛和汇点建立一条边即可。
一个不错的最大流和二分答案的结合。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 350;int head[maxn],level[maxn],cnt,Max_Flow;struct Info{int from,to,c,flow,next;}edge[maxn*maxn*2];void ADD(int u,int v,int w){edge[cnt].from = u;edge[cnt].to = v;edge[cnt].c = edge[cnt].flow = w;edge[cnt].next = head[u];head[u] = cnt++;edge[cnt].from = v;edge[cnt].to = u;edge[cnt].c = edge[cnt].flow = 0;edge[cnt].next = head[v];head[v] = cnt++;}int K,C,M,dist[maxn][maxn];void Make_map(int Max_dist){memset(head,-1,sizeof(head));cnt = Max_Flow = 0;for(int i = 1; i <= K; i++)ADD(i,K+C+1,M);for(int i = K+1; i <= K+C; i++)ADD(0,i,1);for(int i = K+1; i <= K+C; i++)for(int j = 1; j <= K; j++)if(dist[i][j] <= Max_dist)ADD(i,j,1);}int floyd(){int max_dist = 0;for(int k = 1; k <= K+C; k++)for(int i = 1; i <= K+C; i++){if(dist[i][k] == INF)continue;for(int j = 1; j <= K+C; j++){if(dist[k][j] < INF){dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);max_dist = max(max_dist,dist[i][j]);}}}return max_dist;}int bfs(int S,int E){memset(level,-1,sizeof(level));queue<int>Q;level[S] = 0;Q.push(S);while(!Q.empty()){int u = Q.front();Q.pop();for(int i = head[u]; ~i; i = edge[i].next){int v = edge[i].to;if(level[v] == -1 && edge[i].flow > 0){level[v] = level[u]+1;Q.push(v);if(v == E)return 1;}}}return 0;}int Find(int now,int flow,int E){if(now == E)return flow;int os = flow;for(int i = head[now]; ~i; i = edge[i].next){int v = edge[i].to;if(level[v] == level[now]+1 && edge[i].flow > 0){int temp = Find(v,min(flow,edge[i].flow),E);if(!temp)continue;edge[i].flow -= temp;edge[i^1].flow += temp;flow -= temp;}}return os-flow;}int Dinic(int S,int E){while(bfs(S,E)){int temp = Find(S,INF,E);Max_Flow += temp;}return Max_Flow;}int main(){while(~scanf("%d %d %d",&K,&C,&M)){memset(dist,0,sizeof(dist));for(int i = 1; i <= K+C; i++)for(int j = 1; j <= K+C; j++){scanf("%d",&dist[i][j]);if(dist[i][j] == 0)dist[i][j] = INF;}int l = 0,r = floyd();int S = 0,E = C+K+1,ans;while(l <= r){int Mid = (l+r)>>1;Make_map(Mid);int res = Dinic(S,E);if(res == C){ans = Mid;r = Mid-1;}elsel = Mid+1;}printf("%d\n",ans);}return 0;}
阅读全文
1 0
- POJ2112 Optimal Milking(最大流+二分答案)
- poj2112 Optimal Milking --- 最大流,二分
- POJ2112 Optimal Milking 【最大流+二分】
- POJ2112 Optimal Milking (二分+最大流)
- Optimal Milking poj2112 二分+最大流
- POJ2112 Optimal Milking—网络流,最大流,二分
- poj2112--Optimal Milking(二分多重匹配)
- POJ 2112 Optimal Milking 最大流 二分答案
- 【多重二分匹配+网络流】:poj2112,Optimal Milking
- [网络流]poj2112 Optimal Milking
- poj2112 Optimal Milking 最大流(含经典最大流问题总结)
- poj2112 Optimal Milking (Dinic+Floyd+二分)
- poj2112 Optimal Milking dinic/isap+floyed+二分
- POJ 2112 Optimal Milking 二分图最大匹配+二分答案
- floyd +二分答案+最大流 poj2112
- POJ 2112 Optimal Milking(Floyd + 二分 + 最大流)
- poj 2112 Optimal Milking(二分搜索+最大流)
- poj 2112 Optimal Milking(spfa+二分+最大流)
- Linux Centos 6.5_x86安装Nginx
- 剑指offer——23.二叉搜索树的后序遍历
- JSP入门(一)
- 共享单车、共享汽车、其实有的共享创意早在几百年前中国就有了,只是你没发现
- 子父类中子类对象的实例化过程
- POJ2112 Optimal Milking(最大流+二分答案)
- 限制QLineEdit的数值输入范围
- JavaScript难点系列(一):内存空间
- 字符串匹配算法
- Java:Object类详解
- 【Python】安装python包时遇到"error: Microsoft Visual C++ 9.0 is required"问题的解决方法
- Android开发——JVM、Dalvik以及ART的区别
- Hdu6121 Build a tree(2017多校第7场)
- 网易面经-基础知识