POJ2112解题报告【网络流-初级-isap+floyd_warshall+二分】
2012-07-03 15:02
337 查看
题目连接:http://poj.org/problem?id=2112
题意:有C头牛和K个挤奶机,每个挤奶机最多能为M头牛挤奶,他们在农场的不同位置。牛和牛、牛和机器之间可能有路,牛只能沿着路移动。给出路的长度,问要让这些牛都挤完奶,所有牛中走得最远的牛的行走路程最短是多少?
解题思路:首先要建图,把每个牛和挤奶机都看成节点,节点间的边既是他们之间的路的长度。然后用floyd算法,求出每个点之间的最短距离。记录最长的距离,然后二分该距离。再建一个网络流的图,图中包括一个源点、一个汇点、挤奶机的点、牛的点,源点和牛之间都连上容量为1的边,牛和挤奶机之间的距离如果小于mid(之前二分的距离),那么就建立一条容量为1的边,每个挤奶机和汇点之间都建立一条容量为K的边。然后ISAP算法求最大流,如果最大流等于C,向下二分否则向上二分。
算法:ISAP+floyd_walshall+二分
题意:有C头牛和K个挤奶机,每个挤奶机最多能为M头牛挤奶,他们在农场的不同位置。牛和牛、牛和机器之间可能有路,牛只能沿着路移动。给出路的长度,问要让这些牛都挤完奶,所有牛中走得最远的牛的行走路程最短是多少?
解题思路:首先要建图,把每个牛和挤奶机都看成节点,节点间的边既是他们之间的路的长度。然后用floyd算法,求出每个点之间的最短距离。记录最长的距离,然后二分该距离。再建一个网络流的图,图中包括一个源点、一个汇点、挤奶机的点、牛的点,源点和牛之间都连上容量为1的边,牛和挤奶机之间的距离如果小于mid(之前二分的距离),那么就建立一条容量为1的边,每个挤奶机和汇点之间都建立一条容量为K的边。然后ISAP算法求最大流,如果最大流等于C,向下二分否则向上二分。
算法:ISAP+floyd_walshall+二分
#include<cstdio> #include<cstring> #include<queue> #include<stack> #include<cstdlib> #include<algorithm> #include<iostream> #include<map> #include<string> //#define r(x,date) (*((STRUCT*)x).date) //#define dp(i,j) dp[i][j] //#define dp(i,j,k) dp[i][j][k] #define INF 0x7ffffff #define ff(i,from,to) for(i=from;i<=to;i++) #define rff(i,from,to) for(i=from;i>=to;i--) #define ll long long #define MAX_SIDE 110000 #define MAX_NODE 300 #define mset(a,num) memset(a,num,sizeof(a)) using namespace std; template<class T>bool myfun_upmax(T &a,const T&b){return b>a?a=b,1:0;} template<class T>bool myfun_upmin(T &a,const T&b){return b<a?a=b,1:0;} template<class T>void myfun_swap(T &a,T &b){T temp;temp=a;a=b;b=temp;} template<class T>T myfun_max(const T a,const T b){return a>b?a:b;} template<class T>T myfun_min(const T a,const T b){return a<b?a:b;} int cmp(const void *a,const void *b){ return 0; } inline void readint(int &ret) { char c; do { c = getchar(); } while(c < '0' || c > '9'); ret = c - '0'; while((c=getchar()) >= '0' && c <= '9') ret = ret * 10 + ( c - '0' ); } int node[MAX_NODE]; struct SIDE{ int to,next,c; SIDE(){} SIDE(int to,int next,int c):to(to),next(next),c(c){} }side[MAX_SIDE]; int top; void add_side(int u,int v,int c){ side[top]=SIDE(v,node[u],c); node[u]=top++; side[top]=SIDE(u,node[v],0); node[v]=top++; } int START,END,SIZE; int gap[MAX_NODE],pre[MAX_NODE],dis[MAX_NODE],cur[MAX_NODE]; int sap(){ int maxflow=0; int aug=INF; int u=START,v; for(int i=0;i<SIZE;i++){ gap[i]=dis[i]=0; cur[i]=node[i]; } gap[START]=SIZE; pre[START]=START; while(dis[u]<SIZE){ for(int &i=cur[u];i!=-1;i=side[i].next){ v=side[i].to; if( side[i].c && dis[u]==dis[v]+1)break; } if(cur[u]!=-1){ myfun_upmin(aug,side[cur[u]].c); pre[v]=u;u=v; if(u==END){ maxflow+=aug; while(u!=START){ u=pre[u]; side[cur[u]].c-=aug; side[cur[u]^1].c+=aug; } aug=INF; } }else{ int min_dis=SIZE; for(int i=node[u];i!=-1;i=side[i].next){ v=side[i].to; if(side[i].c && myfun_upmin(min_dis,dis[v])) cur[u]=i; } if(--gap[dis[u]]==0)break; ++gap[dis[u]=min_dis+1]; u=pre[u]; } } return maxflow; } int K,C; int N; int matrix[MAX_NODE][MAX_NODE]; int floyd_warshall(){ int MAX=0; for(int k=0;k<N;k++){ for(int i=0;i<N;i++) for(int j=0;j<N;j++){ if(i!=j && matrix[i][k]+matrix[k][j]<matrix[i][j]){ matrix[i][j]=matrix[i][k]+matrix[k][j]; if(matrix[i][j]<INF && matrix[i][j]>MAX) MAX=matrix[i][j]; } } } return MAX; } int M; void build(int limit){ //length not less than the limit top=0; for(int i=0;i<N+2;i++)node[i]=-1; for(int i=0;i<K;i++){ for(int j=K;j<N;j++){ if(matrix[i][j]<=limit) add_side(j,i,1); } } int i; for(i=0;i<K;i++){ add_side(i,END,M); } for(;i<N;i++){ add_side(START,i,1); } } int solve(int low,int high){ while(low<=high){ int mid=low+(high-low)/2; build(mid); int r=sap(); if(r==C)high=mid-1; else low=mid+1; } return low; } int main() { readint(K); readint(C); readint(M); N=K+C; START=N; END=N+1; SIZE=N+2; for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ readint(matrix[i][j]); if(matrix[i][j]==0)matrix[i][j]=INF; } } int max_path=floyd_warshall(); int r=solve(1,max_path); printf("%d\n",r); return 0; }
相关文章推荐
- POJ 2112 Optimal Milking (floyd + 二分 + 网络流)
- POJ 2112 Optimal Milking (二分 + floyd + 网络流)
- Optimal Milking (poj 2112 网络流+二分+floyd)
- POJ-2112 Optimal Milking 二分+网络流
- POJ 2112 Optimal Milking (二分+最短路径+网络流)
- POJ 2112 2391 floyd 二分 最大流
- Ombrophobic Bovines (poj 2391 网络流+二分+Floyd)
- POJ 2112 Optimal Milking, 二分, floyd, 二分图
- BZOJ 4443(SCOI2015)网络流+二分答案 解题报告
- POJ 2112 Optimal Milking 二分图多重匹配 网络流+Floyd+二分
- poj 2112 Optimal Milking 二分 + floyd + 最大流
- 【多重二分匹配+网络流】:poj2112,Optimal Milking
- BZOJ 3993 [SDOI 2015] 网络流+二分答案 解题报告
- poj 2112 Optimal Milking 【最大流 简单题】 【floyd预处理最短路 + 二分 + 最大流】
- POJ 2112 二分+网络流
- POJ 3258 River Hopscotch 解题报告(二分)
- POJ 2112 Optimal Milking【网络流+二分+最短路】
- poj 2112 Optimal Milking(最大流,二分,floyd)
- pku 2112 Optimal Milking floyd + 二分 + 网络流
- POJ2455结题报告【网络流+isap+二分】