POJ2112 Optimal Milking(二分图多重匹配)
题意:
K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j<K+C)。
问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛到产奶机的最远距离最短?最短是多少?
思路:
二分图多重匹配
先用floyd求最短距离
然后跟上一个题一样
不过是奶牛与可达的产奶机建边
依旧是二分答案
/* *********************************************** Author :devil Created Time :2016/5/17 22:7:52 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=235; const int M=35; const int inf=0x3f3f3f3f; int n,m,c,mid,mp[N][N]; bool vis[M]; vector<int>eg[N]; bool Find(int u) { for(int i=0; i<eg[u].size(); i++) { int v=eg[u][i]; if(!vis[v]) { vis[v]=1; if(eg[v].size()<m) { eg[v].push_back(u); return 1; } for(int j=0; j<eg[v].size(); j++) { if(Find(eg[v][j])) { eg[v][j]=u; return 1; } } } } return 0; } bool maxmatch() { for(int i=1; i<=n+c; i++) eg[i].clear(); for(int i=n+1; i<=n+c; i++) for(int j=1; j<=n; j++) if(mp[i][j]<=mid) eg[i].push_back(j); for(int i=n+1; i<=n+c; i++) { memset(vis,0,sizeof(vis)); if(!Find(i)) return 0; } return 1; } void floyd() { for(int k=1; k<=n+c; k++) for(int i=1; i<=n+c; i++) for(int j=1; j<=n+c; j++) if(mp[i][j]>mp[i][k]+mp[k][j]) mp[i][j]=mp[i][k]+mp[k][j]; } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d%d",&n,&c,&m)) { for(int i=1; i<=n+c; i++) for(int j=1; j<=n+c; j++) { scanf("%d",&mp[i][j]); if(!mp[i][j]) mp[i][j]=inf; } floyd(); int l=0,r=(n+c)*200; while(l<r) { mid=(l+r)>>1; if(maxmatch()) r=mid; else l=mid+1; } printf("%d\n",r); } return 0; }