POJ 2112 —— Optimal Milking 二分+Floyd+最大流

原题:http://poj.org/problem?id=2112

#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 250;
int dis[maxn][maxn];
int k, c, m;
int num_nodes;

struct Edge
{
    int from, to, flow, cap;
}edge[maxn*maxn*2];  

vector<int>G[maxn];
int edgenum;
void add(int u, int v, int c)
{
    edge[edgenum].from = u;
    edge[edgenum].to = v;
    edge[edgenum].flow = 0;
    edge[edgenum].cap = c;
    edgenum++;  

    edge[edgenum].from = v;
    edge[edgenum].to = u;
    edge[edgenum].flow = 0;
    edge[edgenum].cap = 0;
    edgenum++;  

    G[u].push_back(edgenum-2);
    G[v].push_back(edgenum-1);
}  

int deep[maxn];
bool vis[maxn];
void BFS(int s, int t)
{
    queue<int>Q;
    memset(vis, false, sizeof vis);
    Q.push(t);
    vis[t] = true;
    deep[t] = 0;
    while(!Q.empty())
    {
        int now = Q.front();
        Q.pop();
        for(int i = 0;i<(int)G[now].size();i++)
        {
            int v = edge[G[now][i]].to;
            if(!vis[v])
			{
                deep[v] = deep[now] + 1;
                vis[v] = true;
                Q.push(v);
            }
        }
    }
}  

int gap[maxn];
int cur[maxn];
int front[maxn];
int Augment(int s, int t)
{
    int minflow = inf;
    int begin = t;
    while(begin != s)
    {
        Edge& e = edge[front[begin]];
        minflow = min(minflow, e.cap - e.flow);
        begin = e.from;
    }  

    begin = t;
    while(begin != s)
    {
        edge[front[begin]].flow += minflow;
        edge[front[begin]^1].flow -= minflow;
        begin = edge[front[begin]].from;
    }
    return minflow;
}  

int Maxflow(int s, int t)
{
    int flow = 0;
    BFS(s, t);
    memset(gap, 0, sizeof gap);
    memset(cur, 0, sizeof cur);
    for(int i = 0;i<num_nodes;i++)  gap[deep[i]]++;
    int begin = s;
    while(deep[s] < num_nodes)
    {
        if(begin == t)
		{
            flow += Augment(s, t);
            begin = s;
        }  

        bool flag = false;
        for(int i = cur[begin];i<(int)G[begin].size();i++)
        {
            Edge& e = edge[G[begin][i]];
            if(e.cap > e.flow && deep[begin] == deep[e.to] + 1)
			{
                front[e.to] = G[begin][i];
                cur[begin] = i;
                flag = true;
                begin = e.to;
                break;
            }
        }  

        if(!flag)
        {
            int k = num_nodes-1;
            for(int i = 0;i<(int)G[begin].size();i++)
			{
                Edge& e = edge[G[begin][i]];
                if(e.cap > e.flow)
                    k = min(k, deep[e.to]);
            }
            if(--gap[deep[begin]] == 0) break;
            gap[deep[begin] = k+1]++;
            cur[begin] = 0;
            if(begin != s)
                begin = edge[front[begin]].from;
        }
    }
    return flow;
}  

void init()
{
    for(int i = 0;i<num_nodes+2;i++) G[i].clear();
    edgenum = 0;
    memset(deep, 0, sizeof deep);
}

void Floyd()
{
	for(int t = 1;t<=k+c;t++)
	{
		for(int i = 1;i<=k+c;i++)
		{
			for(int j = 1;j<=k+c;j++)
			dis[i][j] = min(dis[i][j], dis[i][t]+dis[t][j]);
		}
	}
}

int main()
{
	while(~scanf("%d%d%d", &k, &c, &m))
	{
		for(int i = 1;i<=k+c;i++)
		{
			for(int j = 1;j<=k+c;j++)
			{
				scanf("%d", &dis[i][j]);
				if(i != j && dis[i][j] == 0)
					dis[i][j] = inf;
			}
		}
		Floyd();
		int l = 0, r = 10000;
		int s = 0, t = k+c+1;
		num_nodes = t+1;
		int ans = inf;
		while(l <= r)
		{
			int mid = (l+r)/2;
			init();
			for(int i = k+1;i<=k+c;i++)
			{
				for(int j = 1;j<=k;j++)
				{
					if(dis[i][j] <= mid)
					add(i, j, 1);
				}
			}
			for(int i = k+1;i<=k+c;i++)
				add(s, i, 1);
			for(int i = 1;i<=k;i++)
				add(i, t, m);
			int flow = Maxflow(s, t);
			if(flow != c)
				l = mid + 1;
			else
			{
				ans = min(ans, mid);
				r = mid - 1;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-10-24 20:24:31

POJ 2112 —— Optimal Milking 二分+Floyd+最大流的相关文章

POJ 2112 Optimal Milking 二分答案+最大流

首先二分最长的边,然后删去所有比当前枚举的值长的边,算最大流,看是否能满足所有的牛都能找到挤奶的地方 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include

POJ 2112 Optimal Milking (二分 + 最大流)

题目大意: 在一个农场里面,有k个挤奶机,编号分别是 1..k,有c头奶牛,编号分别是k+1 .. k+c,每个挤奶机一天最让可以挤m头奶牛的奶,奶牛和挤奶机之间用邻接矩阵给出距离.求让所有奶牛都挤到 奶的情况下,走的最远的那头奶牛走的距离最小是多少. 数据保证有解. 算法讨论: 首先可以想到是二分,然后在选择流网络的时候,一开始选择的最小费用最大流,让二分的边权充当最小费用,但是这样跑发现每次二分的是我们要跑的答案,不可行.所以就改用最大流. 最大流肯定是在二分的情况下判定最大流是否等于c,即

POJ 2112 Optimal Milking (二分+最短路+最大流)

<题目链接> 题目大意: 有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径.给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体之间可能没有直接通路. 每台挤奶机可以容纳m头奶牛去挤奶,且每个奶牛仅可以去往一台挤奶机.现在安排这C头奶牛去挤奶,每头奶牛会去往某个挤奶机,求出这C头奶牛去其挤奶的最长路径的最小值. 解题分析: 因为要求最长路径的最小值,所以我们很容易想到二分答案.由于数据量较小,所以我们先用floyed求出所有点之间的最

POJ 2112 Optimal Milking 最优挤奶方案 Floyd算法+二分查找+最大流

题目链接:POJ 2112 Optimal Milking Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12446   Accepted: 4494 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among

POJ 2112 Optimal Milking (二分 + floyd + 网络流)

POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C≤200)头奶牛,在奶牛和挤奶器之间有一组不同长度的路.K个挤奶器的位置用1-K的编号标明,奶牛的位置用K+1-K+C 的编号标明.每台挤奶器每天最多能为M(1≤M≤15)头奶牛挤奶.寻找一个方案,安排每头奶牛到某个挤奶器挤奶,并使得C 头奶牛需要走的所有路程中的最大路程最小.每个测试数据中至少有一

POJ 2112 Optimal Milking(二分+最大流)

POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每个机器能容纳m个奶牛,问所有奶牛都能挤上奶,那么走的距离最大的奶牛的最小值是多少 思路:明显的二分+最大流,注意floyd求出的距离矩阵最大值可能不止200,所以二分的上限要注意 代码: #include <cstdio> #include <cstring> #include <queue> #include <algori

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

POJ 2112 Optimal Milking

Optimal Milking Time Limit: 2000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 211264-bit integer IO format: %lld      Java class name: Main FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures amon

POJ 2112 Optimal Milking(最大流)

题目链接:http://poj.org/problem?id=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