POJ 2112 Floyd + 二分 + 构图 + 最大流
2012-06-15 20:21
225 查看
题目链接: http://poj.org/problem?id=2112
题目大意:
给定K个处理站标号1……K,C头牛编号K+1……K+C,每个处理站最多处理M头牛产的牛奶,处理站和牛之间或者牛与牛之间都有一个距离,牛可以通过相邻边到达处理站或者通过其他牛的所在地到达指定的处理站,问如果合理分配,牛与指定处理站之间的最远距离是多少,保证至少有一种分配。
分析:
首先对于给定的图,需要用Floyd求出所有点之间的最短路(我在求最短路的时候脑残了一下,map[i][j]=0的话也就是没有边应该赋值为无穷大的!!!还有Floyd算法中最外层的循环一定是枚举的中间点!!!还有注意dis[][]相加的时候会产生数据越界的情况!!!慎重!!!)
然后二分枚举一个值mid,进行构图,建立一个超级源点ST,ST向1……K各连一条有向边,容量为M,建立一个超级汇点ED,K+1……K+C分别向ED连一条有向边,容量为1, 然后1……K和K+1……K+C之间如果最短距离dis[ i ][ j ] <= mid,也连一条有向边,容量为1,用Edmond_karp模版求出最大流flow与牛的头数C比较即可得到最终的答案,具体见代码。
代码:
poj2112
题目大意:
给定K个处理站标号1……K,C头牛编号K+1……K+C,每个处理站最多处理M头牛产的牛奶,处理站和牛之间或者牛与牛之间都有一个距离,牛可以通过相邻边到达处理站或者通过其他牛的所在地到达指定的处理站,问如果合理分配,牛与指定处理站之间的最远距离是多少,保证至少有一种分配。
分析:
首先对于给定的图,需要用Floyd求出所有点之间的最短路(我在求最短路的时候脑残了一下,map[i][j]=0的话也就是没有边应该赋值为无穷大的!!!还有Floyd算法中最外层的循环一定是枚举的中间点!!!还有注意dis[][]相加的时候会产生数据越界的情况!!!慎重!!!)
然后二分枚举一个值mid,进行构图,建立一个超级源点ST,ST向1……K各连一条有向边,容量为M,建立一个超级汇点ED,K+1……K+C分别向ED连一条有向边,容量为1, 然后1……K和K+1……K+C之间如果最短距离dis[ i ][ j ] <= mid,也连一条有向边,容量为1,用Edmond_karp模版求出最大流flow与牛的头数C比较即可得到最终的答案,具体见代码。
代码:
poj2112
/*2112 Accepted 920K 485MS C++ 2533B 2012-06-15 15:20:56*/ #include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <vector> using namespace std; #define mpair make_pair #define pii pair<int,int> #define MM(a,b) memset(a,b,sizeof(a)); typedef long long lld; typedef unsigned long long u64; template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;} template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;} #define maxn 240 const int inf= 100000000; ///!!!!!!! int K,C,M; int map[maxn][maxn], dis[maxn][maxn]; int ST,ED,NV; int g[maxn][maxn]; void Floyd(){ for(int i=1;i<ED;++i) for(int j=1;j<ED;++j) dis[i][j]= map[i][j]; for(int k=1;k<ED;++k) for(int i=1;i<ED;++i) if( i!=k ) for(int j=1;j<ED;++j) if( k!=j && i!=j ) up_min( dis[i][j], dis[i][k]+dis[k][j] ); } bool vis[maxn]; int pre[maxn], que[maxn]; bool bfs(){ MM( vis, 0 ); int head= 0, tail= 0; que[tail++]= ST; vis[ST]= 1; while( head<tail ){ int u= que[head++]; for(int v=1;v<NV;++v){ if( g[u][v]>0 && !vis[v] ){ pre[v]= u; if( v==ED ) return 1; que[tail++]= v; vis[v]= 1; } } } return 0; } int Edmond_karp(int len){ for(int i=0;i<NV;++i) for(int j=0;j<NV;++j) g[i][j]= 0; for(int i=1;i<=K;++i) g[ST][i]= M; for(int i=K+1;i<ED;++i) g[i][ED]= 1; for(int i=1;i<=K;++i) for(int j=K+1;j<ED;++j) g[i][j]= (dis[i][j]<=len); int ret= 0; while( bfs() ){ int t= inf; for(int i=ED;i!=ST;i=pre[i]) up_min( t, g[pre[i]][i] ); ret+= t; for(int i=ED;i!=ST;i=pre[i]){ g[pre[i]][i]-= t; g[i][pre[i]]+= t; } } return ret; } int solve(){ int l= 1,r= 100000, mid; while( l<=r ){ mid= (l+r)>>1; if( Edmond_karp(mid) == C ) r= mid-1; else l= mid+1; } return l; } int main() { //freopen("poj2112.in","r",stdin); while( cin>>K>>C>>M ){ ST=0, ED= K+C+1, NV= K+C+2; for(int i=1;i<ED;++i){ for(int j=1;j<ED;++j){ scanf("%d", &map[i][j]); if( map[i][j] == 0 ) map[i][j]= inf; /// !!! } } Floyd(); cout<< solve() <<endl; } }
相关文章推荐
- POJ 2391 floyd + 拆点构图 + 二分 + 最大流
- POJ 2112 Optimal Milking(Floyd + 二分 + 最大流)
- poj 2112 Optimal Milking(最大费用流+dinic算法+二分搜索)
- poj 2112 Optimal Milking 【最大流 简单题】 【floyd预处理最短路 + 二分 + 最大流】
- poj 2112 Optimal Milking, 二分,最短路,最大流
- POJ 2112 二分+最大流
- 【POJ 2391 】Ombr 4000 ophobic Bovines 【floyd +二分+最大流】
- poj 2112 Optimal Milking(最大费用流+dinic算法+二分搜索)
- POJ 2112 Optimal Milking(最大流-Dinic+Floyd+二分)
- poj 2112 Optimal Milking 二分+最大流
- poj 2112 Optimal Milking(二分+最大流)
- POJ 2112 Optimal Milking(最大流+Floyd+二分||二分图匹配)
- poj 2112 Optimal Milking 二分+最大流
- POJ 2112 Optimal Milking (二分 + 最大流)
- POJ 2112 Optimal Milking(最大流+二分)
- poj2112 二分最大流+Floyd
- Optimal Milking POJ - 2112 floyd+二分+最大流
- POJ 2112 Optimal Milking (二分+最短路+最大流or二分图多重匹配)
- POJ 2112 Optimal Milking 最大流 二分答案
- poj 2112 Optimal Milking floyd + 二分 + 最大流