Topic links: http://poj.org/problem?id=2112
The meaning of problems: there are n milking machines, m cows, milking machines each handle up to k cows. Gives the milking machine, the distance between the cows, milking asked after the completion of the task, the most long-distance walking cows minimized and output.
Idea: to minimize the maximum distance, it is easy to know when the binary process. But the dichotomy determine what conditions is it?
Case half of the distance is to set up so cows can go to the milking machine. Such a problem becomes a bipartite graph matching, n milking machine is left, the right is m cows, each cow must match a milking machine. And because the number of hits with a milking machine, is a bipartite graph multiple matches. As long as the maximum number of matches is the number m of the cow's head from the two points it is established. (Multiple bipartite graph matching)
Of course, network flow with the maximum flow is to be completed, generally bipartite graph may flow with the network. Figure that how to build it?
As long build two virtual point, a start point, an end point, the start point is connected to each milking machine, the flow rate is k, each cow connection end points, the flow rate is 1, it is determined whether the cow milking machine may be connected according to the half of the distance, it can be traffic is 1. As long as the maximum flow is m, then the half of the distance is possible.
Of course, there can be a distance between the dots is calculated by floyed.
Multiple Match code bipartite graph:
#include <the iostream> #include <algorithm> #include <cstdio> #include <CString> #include <Queue> #define INF 0x3f3f3f3f the using namespace STD; typedef Long Long LL; const int MAXN = 350 ; int MP [MAXN] [ MAXN]; BOOL Used [MAXN]; int CNT [MAXN]; // CNT [i] of the i-th recording is now the number of cows teat int MAT [MAXN] [MAXN], n-, m, K; // MAT [i] [j] denotes the i-th unit of the j-th matching milking cows who int G [MAXN] [MAXN]; BOOL DFS ( intx) // match { for ( int i = . 1 ; i <= n-; i ++ ) { IF ! (MP [x] [i] && Used [i]) // denotes the x-th cows matching pressing the i-th milk machine { Used [I] = . 1 ; IF (CNT [I] <K) // and does not limit the number of the milking machine, direct match { MAT [I] [CNT [I] ++] = X; return to true ; } the else // maximum number, look on the cow milking machine so if you can make location { for ( int J =0 ; J <K; J ++ ) { IF (DFS (MAT [I] [J])) // allows the position { MAT [I] [J] = X; return to true ; } } } } } return to false ; } BOOL Solve () { for ( int I = n-+ . 1 ; I <= n-m +; I ++) // see if it matches the cows { for ( int J = . 1; J <= n-; J ++ ) Used [J] = 0 ; IF (! DFS (I)) // I do not match cows return to false ; } return to true ; } BOOL Check ( int X) // determination condition, a distance x is established { Memset (CNT, 0 , the sizeof (CNT)); Memset (MP, 0 , the sizeof (MP)); for ( int I = . 1 ; I <= n-; I ++ ) for ( int J = n-+ . 1;j<=m+n;j++) if(g[i][j]<=x) mp[i][j]=mp[j][i]=1; if(solve()) return true; return false; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n+m;i++) { for(int j=1;j<=n+m;j++) { scanf("%d",&g[i][j]); if(i!=j&&!g[i][j]) g[i][j]=inf; } } for(int k=1;k<=n+m;k++)//floyed求最短距离 for(int i=1;i<=n+m;i++) for(int j=1;j<=n+m;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); int l=0,r=inf,mid; while(r>=l)//Dichotomous outcomes { MID = (R & lt + L) / 2 ; IF (Check (MID)) R & lt = mid- . 1 ; the else L = MID + . 1 ; } the printf ( " % D \ n- " , L); return 0 ; }
Network flow Code:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=350; int g[maxn][maxn]; struct node{ int u,v,w,nxt; }e[maxn*maxn]; int h[maxn],depth[maxn],n,m,k,st,ed; int cnt; void add(int u,int v,int W) // build FIG remember reverse sides built { E [CNT] .v = V; E [CNT] .W = W; E [CNT] .nxt = H [U]; H [U] = CNT ++ ; E [CNT] .v = U, E [CNT] .W = 0 ; E [CNT] .nxt = H [V]; H [V] = CNT ++ ; } BOOL BFS () { // dinic-- minutes FIG layer Queue < int > que; Memset (depth, 0 , the sizeof (depth)); que.push (ST); depth [ST] = . 1 ; the while (! que.empty ()) { int U =que.front(); que.pop(); if(u==ed) return true; for(int i=h[u];i!=-1;i=e[i].nxt){ int v=e[i].v; int w=e[i].w; if(!depth[v]&&w){ depth[v]=depth[u]+1; que.push(v); } } } return false; } int dfs(int u,int dis) { if(u==ed) return dis; int res=0; for(int i=h[u];i!=-1;i=e[i].nxt) { int v=e[i].v; int w=e[i].w; if((depth[v]==depth[u]+1)&&w) { int di=dfs(v,min(w,dis-res)); e[i].w-=di; e[i^1].w+=di; res+=di; if(res==dis) return dis; } } return res; } int dinic()//dinic求最大流 { int ans=0; while(bfs()) { ans+=dfs(st,inf); } return ans; } bool check(int x) { cnt=0; memset(h,-1,sizeof(h)); for( Int I = . 1 ; I <= n-; I ++) // milking machine and cows can connect for ( int J = n-+ . 1 ; J <= n-+ m; J ++ ) IF (G [I] [J] < = X) the Add (I, J, . 1 ); for ( int I = . 1 ; I <= n-; I ++) // start point connected milking machine the Add (ST, I, K); for ( int I = n-+ . 1 ; I <= n-m +; I ++) // cows even end the Add (I, ED, . 1 ); int ANS = Dinic (); IF (ANS == m)//最大流是奶牛头数 return true; return false; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n+m;i++) { for(int j=1;j<=n+m;j++) { scanf("%d",&g[i][j]); if(i!=j&&!g[i][j]) g[i][j]=inf; } } for(int k=1;k<=n+m;k++) for(int i=1;i<=n+m;i++) for(int j=1;j<=n+m;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); st=0,ed=n+m+1;//建起点,终点 int l=0,r=inf,mid; while(r>=l) { mid=(r+l)/2; if(check(mid)) r=mid-1; else l=mid+1; } printf("%d\n",l); return 0; }