poj 2112 floyd+最大流(所有牛挤奶走的最长路的最小值)
来源:互联网 发布:mac官网唇膏体验装 编辑:程序博客网 时间:2024/04/30 21:25
题意:给定K台挤奶机器和C头牛,每台挤奶机只能供M头牛挤奶。现在给出(K + C)*(K + C)的距离矩阵,表示第i个物体到第j个物体之间的路径长度,若此值为零,则说明其间不可直接到达。问怎么安排这C头牛到K台机器挤奶,使得需要走最长路程到挤奶机器的奶牛所走的路程最少,并求出这个最小值。
思路:首先利用Floyd算法求出每个奶牛到每个挤奶机的最短距离。
此后二分答案,先假定一个最大距离的的最小值 maxdist, 对每个maxdist值,都重新构图。 构图策略是:每个奶牛和挤奶器都是一个节点,添加一个源,连边到所有奶牛节点,这些边容量都是1。添加一个汇点,每个挤奶器都连边到它。这些边的容量都是M。如果奶牛节点i和挤奶器节点j之间的距离<= maxdist,则从i节点连一条边到j节点,表示奶牛i可以到挤奶器j去挤奶。该边容量为1。该图上的最大流如果是C(奶牛数),那么就说明假设的 maxdist成立,则减小 maxdist再试。
注意二分过程,设下界为low,上界为high。当最大流等于奶牛数量时,如果maxdist值等于low则返回答案,否则是high=maxdist(传统的二分查找是high=mid-1,这里相当于等于mid,不减一);当最大流小于奶牛数量时,使low=maxdist+1。
版本2用邻接表建图,且最大流算法的队列用stl实现。
内容部分参考北大郭炜老师的课件.
#include <stdio.h>#include <string.h>#define min(a,b) a<b?a:b#define max(a,b) a>b?a:b#define N 235int n,m,thresh;int dis[N][N],c[N][N],a[N],p[N],q[200000];void createmap(int res){int i,j;memset(c,0,sizeof(c));for(i = 1;i<=m;i++)//源点到牛c[0][i] = 1;for(i = m+1;i<=n+m;i++)//机器到汇点c[i][n+m+1] = thresh;for(i = 0;i<n;i++)//牛到机器for(j = n;j<n+m;j++)if(dis[i][j] <= res)c[j-n+1][i+m+1] = 1;}int maxflow(int s,int t){//最大流int front,rear,i,res=0;while(1){front = rear = -1;memset(a,0,sizeof(a));memset(p,0,sizeof(p));a[s] = 0x3fffffff;q[++rear] = s;while(front < rear){int now = q[++front];for(i = 0;i<=t;i++)if(!a[i] && c[now][i]>0){a[i] = min(a[now],c[now][i]);p[i] = now;q[++rear] = i;}}if(!a[t])break;res += a[t];for(i = t;i!=s;i=p[i]){c[p[i]][i] -= a[t];c[i][p[i]] += a[t];}}return res;}int main(){freopen("a.txt","r",stdin);while(scanf("%d %d %d",&n,&m,&thresh)!=EOF){int i,j,k,res,high=0,low=0;for(i = 0;i<n+m;i++)for(j = 0;j<n+m;j++){scanf("%d",&dis[i][j]);if(dis[i][j] == 0)dis[i][j] = 0x3fffffff;}//floydfor(k = 0;k<n+m;k++)for(i = 0;i<n+m;i++)for(j = 0;j<n+m;j++)dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);//确定二分上界highfor(i = 0;i<n;i++)for(j = n;j<n+m;j++)high = max(high,dis[i][j]);//二分答案while(low <= high){res = (low+high)/2;createmap(res);//每次都得重新建图if(m == maxflow(0,n+m+1)){if(res == low)break;high = res;//这是与传统二分查找不一样的地方}elselow = res+1;}printf("%d\n",res);}return 0;}
版本2:
#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <queue>#include <cstdlib>using namespace std;#define INF 0x3fffffff#define clc(s,t) memset(s,t,sizeof(s))#define N 235int m,c,n,k;int dis[N][N];struct edge{ int y,next,c;}e[N*N*2];int first[N],top;void addedge(int x,int y,int c){ e[top].y = y; e[top].c = c; e[top].next = first[x]; first[x] = top++;}void add(int x,int y,int c){ addedge(x,y,c); addedge(y,x,0);}void create(int d){ int i,j; clc(first,-1); top = 0; for(i = 1;i<=m;i++) add(0,i,k); for(i = m+1;i<=m+c;i++) add(i,n+1,1); for(i = 1;i<=m;i++) for(j = m+1;j<=m+c;j++) if(dis[i][j] <= d) add(i,j,1);}int maxflow(){ queue<int> q; int i,now,res=0,p[N],a[N],id[N]; while(1){ clc(p,0); clc(a,0); a[0] = INF; q.push(0); while(!q.empty()){ now = q.front(); q.pop(); for(i = first[now];i!=-1;i=e[i].next){ if(!a[e[i].y] && e[i].c>0){ a[e[i].y] = min(a[now],e[i].c); p[e[i].y] = now; id[e[i].y] = i; q.push(e[i].y); } } } if(a[n+1] == 0) break; res+=a[n+1]; for(i = n+1;i!=0;i=p[i]){ e[id[i]].c -= a[n+1]; e[id[i]^1].c += a[n+1]; } } return res;}int main(){ while(scanf("%d %d %d",&m,&c,&k)!=EOF){ int i,j,w,low,high,mid; n = m+c; high = 0; for(i = 1;i<=n;i++) for(j = 1;j<=n;j++){ scanf("%d",&dis[i][j]); if(i!=j && dis[i][j] == 0) dis[i][j] = INF; } for(w = 1;w<=n;w++) for(i = 1;i<=n;i++) for(j = 1;j<=n;j++) dis[i][j] = min(dis[i][j],dis[i][w]+dis[w][j]); high = 46000; low = 0; while(low < high){ mid = (low+high)>>1; create(mid); if(maxflow() == c) high = mid; else low = mid+1; } printf("%d\n",low); } return 0;}
0 0
- poj 2112 floyd+最大流(所有牛挤奶走的最长路的最小值)
- (POJ 2253)Frogger 求所有可达路径中的最大边的最小值 dijkstra || floyd 变形
- POJ 2253 floyd求最大边的最小值
- poj2112Optimal Milking(最优秀的挤奶方案)——floyd+最大流+二分
- bzoj 1733: [Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 (二分+最大流)
- [BZOJ1733][Usaco2005 feb]Secret Milking Machine 神秘的挤奶机(二分+最大流)
- POJ 2112--Optimal Milking【二分找最大距离的最小值 && 最大流dinic】
- poj2522 Frogger(最短路变形 所有路径中最长边的最小值)
- POJ 2112 Optimal Milking(Floyd + 二分 + 最大流)
- poj 2112 Optimal Milking (最大流+二分+floyd)
- poj 2112 Optimal Milking(floyd+二分+最大流)
- POJ 2112 Optimal Milking(最大流-Dinic+Floyd+二分)
- poj 2112 Optimal Milking(floyd+二分+最大流)
- poj 2112 Optimal Milking(最大流,二分,floyd)
- poj 2112 最大流+floyd+二分答案
- POJ 2112 floyd+二分最大流
- POJ 2112 2391 floyd 二分 最大流
- poj 2135 最小费用最大流(从1到n往返不走重复路的最小距离)
- iOS音频的后台播放
- hdu 1528 Card Game Cheater 二分图的经典应用
- Unique Paths 解题研究,面试题练习第三天
- hdoj.2023 求平均成绩 20140726
- WCF基础
- poj 2112 floyd+最大流(所有牛挤奶走的最长路的最小值)
- realloc的全面解析
- 7.29 继续完善计算器界面
- Eclipse设置tab键为空格键缩进
- 获取视频文件的缩略图
- THE DEAD-SIMPLE STEP-BY-STEP GUIDE FOR FRONT-END DEVELOPERS TO GETTING UP AND RUNNING WITH NODE.JS,
- cocos2d-x wp8 中文显示问题
- EJB到底是什么,真的那么神秘吗??
- Android无线调试