题目大意是:K台挤奶机器,C头牛,K不超过30,C不超过200,每台挤奶机器最多可以为M台牛工作,给出这些牛和机器之间,牛和牛之间,机器与机器之间的距离,在保证让最多的牛都有机器挤奶的情况下,给出其中最长的一头牛移动的距离的最小值。
首先用Floyd求出任意两点之间的最短距离,然后再用二分法限定最多的移动距离d,在求最大流时,搜索增广路的时候同时也判断距离有没有超过d就行了。
#include <stdlib.h> #include <stdio.h> #include <vector> #include <math.h> #include <string.h> #include <string> #include <iostream> #include <queue> #include <list> #include <algorithm> #include <stack> #include <map> #include<iostream> #include<cstdio> using namespace std; #define MAXN 250 #define MAXDIS 100000 int G[MAXN][MAXN]; int D[MAXN][MAXN]; int Flow[MAXN][MAXN]; int Flow1[MAXN][MAXN]; bool Visited[MAXN]; void Floyd(int n) { for (int i = 0; i < n + 2; i++) { for (int j = 0; j < n + 2; j++) { D[i][j] = MAXDIS; if (G[i][j] > 0) { D[i][j] = G[i][j]; } if (i == j) { D[i][j] = 0; } } } for (int k = 0; k < n;k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n;j++) { D[i][j] = min(D[i][j], D[i][k] + D[k][j]); } } } } int dfs(int s,int t, int f,int n, int limit) { if (s == t) { return f; } Visited[s] = true; for (int i = 0; i < n; i++) { if (!Visited[i] && Flow[s][i] > 0 && D[s][i] <= limit) { Visited[i] = true; int d = dfs(i, t, min(f, Flow[s][i]), n, limit); if (d > 0) { Flow[s][i] -= d; Flow[i][s] += d; return d; } } } return 0; } int MaxFlow(int s, int t,int n, int limit) { memset(Visited, 0, sizeof(Visited)); int f = 0; int d = 0; while ((d=dfs(s, t, 1, n, limit)) > 0) { memset(Visited, 0, sizeof(Visited)); f += d; } return f; } int main() { #ifdef _DEBUG freopen("d:\\in.txt", "r", stdin); #endif int K, C, M; scanf("%d %d %d", &K, &C, &M); memset(G, 0, sizeof(G)); for (int i = 0; i < K + C; i++) { for (int j = 0; j < K + C;j++) { int value; scanf("%d", &value); G[i][j] = value; } } Floyd(K + C); for (int i = 0; i < K + C; i++) { D[i][K + C] = 0; D[K + C][i] = 0; D[i][K + C + 1] = 0; D[K + C + 1][i] = 0; } memset(Flow, 0, sizeof(Flow)); for (int i = 0; i < K;i++) { Flow[i][K + C + 1] = M; } int maxflow = min(C, K * M); for (int i = K; i < K + C;i++) { Flow[K + C][i] = 1; for (int j = 0; j < K;j++) { Flow[i][j] = 1; } } int l = 0; int r = MAXDIS; memcpy(Flow1, Flow, sizeof(Flow)); while (r - l > 1) { memcpy(Flow, Flow1, sizeof(Flow)); int mid = (l + r) / 2; int f = MaxFlow(K + C, K + C + 1, K + C + 2, mid); if (f >= maxflow) { r = mid; } else l = mid; } printf("%d\n", r); return 0; }
POJ2112 Optimal Milking 二分法+网络流
时间: 2024-10-02 20:13:14