POJ 2112 Optimal Milking(二分+floyd+最大流)
来源:互联网 发布:地方门户 php 编辑:程序博客网 时间:2024/04/29 05:19
POJ 2112 Optimal Milking(二分+floyd+最大流)
http://poj.org/problem?id=2112
题意:
k个机器,每个机器最多服务m头牛。
c头牛,每个牛需要1台机器来服务。
告诉你牛与机器(牛与牛,机器与机器)每个之间的直接距离。
问:让所有的牛都被服务的情况下,使走的最远的牛的距离最短,求这个距离。
分析:
首先用floyd算法求出任意两点(牛或机器)之间的最短距离.
然后我们二分该距离,建立网络流图.假设我们当前二分的距离为x.
首先是源点s到任意牛i之间有边(s,i,1).
然后是任意机器j到汇点t之间有边(j,t,m).
然后对于任意牛i和机器j,如果他们之间的距离<=x,那么就添加一条(i,j,1)的边.
最终我们求最大流,看看最大流是否等于牛的数目C即可.
AC代码:
#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define INF 1e9using namespace std;const int maxn=300+10;struct Edge{ int from,to,cap,flow; Edge(){} Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}};struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; int d[maxn]; int cur[maxn]; bool vis[maxn]; void init(int n,int s,int t) { this->n=n, this->s=s, this->t=t; edges.clear(); for(int i=0;i<n;i++) G[i].clear(); } void AddEdge(int from,int to,int cap) { edges.push_back( Edge(from,to,cap,0) ); edges.push_back( Edge(to,from,0,0) ); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { queue<int> Q; memset(vis,0,sizeof(vis)); d[s]=0; vis[s]=true; Q.push(s); while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0;i<G[x].size();i++) { Edge& e=edges[G[x][i]]; if(!vis[e.to] && e.cap>e.flow) { vis[e.to]=true; Q.push(e.to); d[e.to]=d[x]+1; } } } return vis[t]; } int DFS(int x,int a) { if(x==t || a==0) return a; int flow=0,f; for(int& i=cur[x];i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } int max_flow() { int ans=0; while(BFS()) { memset(cur,0,sizeof(cur)); ans+=DFS(s,INF); } return ans; }}DC;int K,C,M;int src,dst;int dist[maxn][maxn];void floyd(int n){ for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(dist[i][k]<INF && dist[k][j]<INF) dist[i][j]=min(dist[i][j], dist[i][k]+dist[k][j]);}bool solve(int limit){ DC.init(K+C+2,src,dst); for(int i=1;i<=C;i++) DC.AddEdge(src,K+i,1); for(int i=1;i<=K;i++) DC.AddEdge(i,dst,M); for(int i=1;i<=C;i++) for(int j=1;j<=K;j++) if(dist[i+K][j]<=limit) DC.AddEdge(i+K,j,1); return DC.max_flow()==C;}int main(){ while(scanf("%d%d%d",&K,&C,&M)==3) { int n=K+C; src=0,dst=K+C+1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dist[i][j]= i==j?0:INF; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&dist[i][j]); if(i!=j && dist[i][j]==0) dist[i][j]=INF; } floyd(n); int L=0,R=0; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(dist[i][j]<INF) R=max(R,dist[i][j]); while(R>L) { int mid= L+(R-L)/2; if(solve(mid)) R=mid; else L=mid+1; } printf("%d\n",R); } return 0;}
0 0
- 【最大流+floyd+二分+dinic】北大 poj 2112 Optimal Milking
- POJ 2112 Optimal Milking(Floyd + 二分 + 最大流)
- POJ 2112 Optimal Milking 二分+floyd+最大流
- POJ 2112 - Optimal Milking Floyd+二分+最大流
- POJ 2112 Optimal Milking(二分+floyd+最大流)
- 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 —— Optimal Milking 二分+Floyd+最大流
- poj 2112 Optimal Milking(floyd+二分+最大流)
- poj 2112 Optimal Milking(二分+Floyd+最大流)
- Poj 2112 Optimal Milking【Floyd+二分+最大流Dinic】
- 【POJ- 2112】Optimal Milking 【floyd+二分+最大流】
- poj 2112 Optimal Milking(最大流,二分,floyd)
- POJ 2112.Optimal Milking【Floyd+二分+最大流】
- 控件实战技巧笔记
- MFC编程若干心得
- poj1129 Channel Allocation 染色问题
- input value 属性遇到引号不显示的解决方法
- linux配置monit自动监控程序运行状态
- POJ 2112 Optimal Milking(二分+floyd+最大流)
- Android 的权限设置大全
- oracle细粒度审计脚本批量生成
- linux下几个简易的系统监控脚本
- Android开发EditText属性
- OpenCV中的HOG+SVM物体分类
- Linux下修改root密码以及找回密码的方法
- 找朋友(bfs)搜索(还有队列思想)
- 程序、进程、作业之间的区别与联系