zoukankan      html  css  js  c++  java
  • POJ 2112 Optimal Milking(Floyd+多重匹配+二分枚举)

    题意:有K台挤奶机,C头奶牛,每个挤奶机每天只能为M头奶牛服务,下面给的K+C的矩阵,是形容相互之间的距离,求出来走最远的那头奶牛要走多远
     
    输入数据:
    第一行三个数 K, C, M 
    接下来是  (K+C)*(K+C)的矩阵
    表示每个物体之间的距离, 0 表示两者之间是不通的。
    挤奶机 1, 挤奶机2 .... 挤奶机 K, 奶牛1,奶牛2...奶牛M
    题目思路:
    对输入进来的数据先进行闭包传递,然后再对奶牛到挤奶机的距离进行二分枚举,枚举出来的值进行多重匹配
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define INF 0x3fffffff
    #define maxn 1255
    int n, m, k;///n个挤奶机  m只奶牛  每台挤奶机最多挤 k只
    bool vis[maxn];
    int G[maxn][maxn], Dis[100000], DisNum;
    vector<vector<int> > P;///用来保存匹配的数据
    
    void Floyd()
    {
        int len = n + m;
        DisNum = 0;
        for(int k=0; k < len; k++)
        {
            for(int i=0; i < len; i++)
            {
                for(int j=0; j < len; j++)
                    G[i][j] = min(G[i][j], G[i][k]+G[k][j]);
            }
        }
    
        for(int i=0; i<len; i++)
        {
            for(int j=0; j<len; j++)
                Dis[DisNum ++] = G[i][j];
        }
    }
    bool Find(int u,int limt)
    {
        for(int i=0; i<n; i++)
        {
            if(!vis[i] && G[u][i] <= limt)
            {
                vis[i] = true;
                if(P[i].size() < k)
                {
                    P[i].push_back(u);
                    return true;
                }
                for(int j=0; j<P[i].size(); j++)
                {
                    if( Find(P[i][j], limt) )
                    {
                        P[i].erase(P[i].begin()+j);
                        P[i].push_back(u);
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    bool solve(int limt)
    {
        P.clear();
        P.resize(n+1);
        for(int i=n; i<n+m; i++)
        {
            memset(vis, false, sizeof(vis));
            if( !Find(i,limt) )
                return false;
        }
        return true;
    }
    
    int main()
    {
        while(scanf("%d %d %d", &n, &m, &k) != EOF)
        {
            for(int i=0; i<n+m; i++)
            {
                for(int j=0; j<n+m; j++)
                {
                    scanf("%d", &G[i][j]);
                    if(!G[i][j]) G[i][j] = INF;
                }
    
            }
            Floyd();///先进行一下闭包传递
            sort(Dis,Dis + DisNum);
            int L = 0, R = DisNum - 1;
    
            while(L < R)
            {
                int mid = (L + R) / 2;
                if( solve(Dis[mid]) )
                    R = mid;
                else
                    L = mid + 1;
            }
            printf("%d
    ", Dis[R]);
        }
        return 0;
    }
  • 相关阅读:
    关于等价类测试的简单实践 20150322
    对软件测试的理解 20150314
    pthread_wrap.h
    libuv 错误号UV_ECANCELED 的处理
    简单的后台日志组件
    Windows NTService 后台框架封装
    检查程序进程是否存在/强制杀掉程序进程
    析构函数结束线程测试
    移动天线
    猜数字游戏的Java小程序
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718616.html
Copyright © 2011-2022 走看看