Optimal Milking(二分图多重匹配+二分)(网络流)

Optimal Milking

Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d
& %I64u

Submit Status Practice POJ
2112

Description

FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) cows. A set of paths of various lengths runs among the cows and the milking machines. The milking machine locations are named by ID numbers 1..K; the cow
locations are named by ID numbers K+1..K+C.

Each milking point can "process" at most M (1 <= M <= 15) cows each day.

Write a program to find an assignment for each cow to some milking machine so that the distance the furthest-walking cow travels is minimized (and, of course, the milking machines are not overutilized). At least one legal assignment is possible for all input
data sets. Cows can traverse several paths on the way to their milking machine.

Input

* Line 1: A single line with three space-separated integers: K, C, and M.

* Lines 2.. ...: Each of these K+C lines of K+C space-separated integers describes the distances between pairs of various entities. The input forms a symmetric matrix. Line 2 tells the distances from milking machine 1 to each of the other entities; line 3 tells
the distances from machine 2 to each of the other entities, and so on. Distances of entities directly connected by a path are positive integers no larger than 200. Entities not directly connected by a path have a distance of 0. The distance from an entity
to itself (i.e., all numbers on the diagonal) is also given as 0. To keep the input lines of reasonable length, when K+C > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its
own line.

Output

A single line with a single integer that is the minimum possible total distance for the furthest walking cow.

Sample Input

2 3 2
0 3 2 1 1
3 0 3 2 0
2 3 0 1 0
1 2 1 0 2
1 0 0 2 0

Sample Output

2

题意:K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j<K+C)。

问题:如何安排使得在任何一头奶牛都有自己产奶机的条件下,奶牛到产奶机的最远距离最短?最短是多少?

解:问最远距离最小是肯定是二分查找啦,二分距离,二分图多重匹配判断能否满流;

使用二分图多重匹配+二分方式

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=300,inf=0x3f3f3f3f,M=300,N=300;
int mp[maxn][maxn],map[maxn][maxn];
int vlink[M],link[M][N];
bool vis[M];
int k,c,w;

int path(int s)
{
    for(int i=0;i<k;i++)///挤奶器集合
    {
        if(map[s][i] && !vis[i])
        {
            vis[i]=true;
            if(vlink[i]<w)///机器可用上限
            {
                link[i][vlink[i]++]=s;
                return 1;
            }
            for(int j=0;j<vlink[i];j++)
            {
                if(path(link[i][j]))
                {
                    link[i][j]=s;
                    return 1;
                }
            }
        }
    }
    return 0;
}
bool max_match()
{
    int ans=0;
    memset(vlink,0,sizeof(vlink));
    for(int i=0;i<c;i++)///奶牛集合
    {
        memset(vis,false,sizeof(vis));
        if(!path(i))
        return false;
    }
    return true ;///所有奶牛都有一个挤奶器返回真
}

int main()
{
    while(~scanf("%d%d%d",&k,&c,&w))
    {
        for(int i=0;i<c+k;i++)
        {
            for(int j=0;j<k+c;j++)
            {
                scanf("%d",&mp[i][j]);
                if(mp[i][j]==0)///这里一定要修改,不然会影响floyd算法,
                    mp[i][j]=inf;
            }
        }
        ///floyd必须求
        for(int i=0;i<k+c;i++)
        {
            for(int j=0;j<k+c;j++)
            {
                for(int l=0;l<k+c;l++)
                {
                    if(mp[j][l]>mp[j][i]+mp[i][l])
                        mp[j][l]=mp[j][i]+mp[i][l];
                }
            }
        }
        int l=0,r=inf,mid;
        while(l<r)
        {
            mid=(l+r)/2;
            memset(map,0,sizeof(map));
            for(int i=k;i<c+k;i++)///奶牛->机器
            {
               for(int j=0;j<k;j++)
               {
                  if(mp[i][j]<=mid)///二分查找最短距离
                    map[i-k][j]=1;
               }
            }
            if(max_match())///二分图多重匹配,奶牛都有机器用时减小上线
                r=mid;
            else
                l=mid+1;
        }
        cout<<r<<endl;

    }
    return 0;
}

网络流+二分(两种方式大同小异)

题目描述:
农场主John将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C≤200)头奶牛,在奶
牛和挤奶器之间有一组不同长度的路。K个挤奶器的位置用1~K的编号标明,奶牛的位置用K+1~
K+C的编号标明。
每台挤奶器每天最多能为M(1≤M≤15)头奶牛挤奶。
编写程序,寻找一个方案,安排每头奶牛到某个挤奶器挤奶,并使得C头奶牛需要走的所有
路程中的最大路程最小。每个测试数据中至少有一个安排方案。每条奶牛到挤奶器有多条路。
// 本题的求解算法:先用Floyd算法求出能达到的任意两点之间的最短路径,然后用Dinic算法
// 求最大流;搜索最大距离的最小值采用二分法进行。

// 建图问题 : 给个源点 s 。源点到奶牛的流量为1 如果奶牛到达挤奶器距离在max_min范围内 那没就然 该奶牛到该挤奶器的流量为1
// 再给个汇点  那么挤奶器到汇点的流量就是M 正好符合限制
/// 然后二分查找 max_min就可以了
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define INF 1000000000
#define maxn 310
#define maxm 48010
#define LL  __int64//long long
int M,K,C,N;
int cap[maxn][maxn],flow[maxn][maxn];
int dis[maxn][maxn];//,bl[1100];
void build(int max_min){  // 建图
    int i,j;
    memset(cap,0,sizeof(cap));
    memset(flow,0,sizeof(flow));
   for(i=1;i<=K;i++) cap[i][N+1]=M;
   for(i=K+1;i<=N;i++) cap[0][i]=1;
   for(i=K+1;i<=N;i++)
    for(j=1;j<=K;j++)
     if(dis[i][j]<=max_min) cap[i][j]=1;
}
int level[maxn];
bool BFS(int s,int t){
   memset(level,0,sizeof(level));
   queue<int> Q;
   int u;
   int i;
   Q.push(s);
   level[s]=1;
   while(!Q.empty()){
      u=Q.front();
      Q.pop();
      if(u==t) return true;
      for(i=1;i<=t;i++)
        if(!level[i]&&cap[u][i]>flow[u][i])
        {
            level[i]=level[u]+1;
            Q.push(i);
        }
   }
   return false;
}
int dfs(int u,int maxf,int t){
    if(u==t||maxf==0) return maxf;
    int ret=0,f,i;
    for(i=1;i<=t;i++)
      if(cap[u][i]>flow[u][i]&&level[u]+1==level[i]){
           f= dfs(i,min(maxf,cap[u][i]-flow[u][i]),t);
           flow[u][i]+=f;
           flow[i][u]-=f;
           maxf-=f;
           ret+=f;
           if(maxf==0) break;
    }
    return ret;
}
int Dinic(int s,int t){
   int flow=0;
   while(BFS(s,t)){
    flow+=dfs(s,INF,t);
   }
   return flow;
}
void init(){
   // memset(cap,0,sizeof(cap));
  //  memset(flow,0,sizeof(flow));
}
int main(){
    int i,j,k;
   while(scanf("%d %d %d",&K,&C,&M)!=EOF){

    N=K+C;
    for(i=1;i<=N;i++)
       for(j=1;j<=N;j++){
        scanf("%d",&dis[i][j]);
        if(dis[i][j]==0) dis[i][j]=INF;
    }
    for(k=1;k<=N;k++)
       for(i=1;i<=N;i++)
         for(j=1;j<=N;j++)
            if(dis[i][j]>dis[i][k]+dis[k][j])
              dis[i][j]=dis[i][k]+dis[k][j];
    /* for(i=0;i<=N+1;i++,printf("\n"))
        for(k=0;k<=N+1;k++)
         printf("%d ",cap[i][k]);*/
      int L=0,R=100000,mid;
      int tp;
      while(L<R){// 二分枚举 max_min
         mid=(L+R)>>1;
         build(mid);
         tp=Dinic(0,N+1);
         if(tp>=C) R=mid;
         else L=mid+1;
      }
     printf("%d\n",R);
   }

   return 0;
}
时间: 2024-07-30 00:32:34

Optimal Milking(二分图多重匹配+二分)(网络流)的相关文章

Jamie&#39;s Contact Groups(二分图多重匹配+二分)(网络流)

Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2289 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list

POJ--2289--Jamie&#39;s Contact Groups【二分图多重匹配+二分答案】

链接:http://poj.org/problem?id=2289 题意:有n个人,m个分组,每个人可以分配到一些组别,问如何分能使得人数最多的组别人数最少. 思路:这道题二分+网络流也可以做,我这里是二分图多重匹配的做法.因为一个组别是一对多的关系,所以是多重匹配,我们二分多重匹配的限制,得到最小的限制可使二分图匹配,这个限制就是答案. 网上找的模板 #include<cstring> #include<string> #include<fstream> #inclu

POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 20262   Accepted: 7230 Case Time Limit: 1000MS Description: FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) c

hiho 第117周 二分图多重匹配,网络流解决

描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加a[i]项比赛,并且给出他所擅长的b[i]项比赛的编号. 小Hi和小Ho希望将每个学生都安排到他所擅长的比赛项目,

HDU 1669 二分图多重匹配+二分

Jamie's Contact Groups Time Limit: 15000/7000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 747    Accepted Submission(s): 303 Problem Description Jamie is a very popular girl and has quite a lot of friends, so she

POJ 2112—— Optimal Milking——————【多重匹配、二分枚举答案、floyd预处理】

Optimal Milking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2112 Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 20

Steady Cow Assignment(二分图多重匹配+二分)(网络流)

Steady Cow Assignment Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3189 Description Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of cou

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知道什么是最小点覆盖,我也在这里说一下:假如选

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加