博客
关于我
poj 2112 最优挤奶方案
阅读量:793 次
发布时间:2023-03-03

本文共 3500 字,大约阅读时间需要 11 分钟。

为了解决这个问题,我们需要找到一种方法来分配每头牛到一个挤奶机,使得最远走的那头牛的总行走距离最小。这个问题可以通过计算每头牛到每个挤奶机的最短距离,并使用最大流算法来确定最优分配方案。

方法思路

  • 计算最短距离:使用Floyd-Warshall算法计算所有牛到所有挤奶机的最短距离。
  • 流网络构建:将问题转化为最大流问题。构建一个流网络,其中源点连接所有牛,牛连接到挤奶机,挤奶机连接到汇点。
  • 二分搜索优化:使用二分搜索来确定最小的最大距离。对于每个中间值,使用最大流算法检查是否存在可行的分配方案。
  • 解决代码

    #include 
    #include
    #include
    #include
    using namespace std;
    struct Edge {
    int to, rev;
    int capacity;
    };
    vector
    > graph; void add_edge(int u, int v, int cap) { Edge e = {v, graph[v].size(), cap}; Edge r = {u, graph[u].size(), 0}; graph[u].push_back(e); graph[v].push_back(r); } int bfs(int s, int t) { vector
    dist(s + 1, -1); queue
    q; dist[s] = 0; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (const auto& e : graph[u]) { if (e.capacity > 0 && dist[e.to] == -1) { dist[e.to] = dist[u] + 1; q.push(e.to); } } } return dist[t] != -1; } int dfs(int u, int t, int flow) { if (u == t) return flow; vector
    ptr(u + 1, 0); for (int i = 0; i < graph[u].size(); ++i) { if (graph[u][i].capacity > 0 && dist[u][i] != -1) { if (ptr[i] == 0) { ptr[i] = graph[u][i].capacity; int min_flow = min(flow, graph[u][i].capacity); int res = dfs(graph[u][i].to, t, min_flow); if (res > 0) { graph[u][i].capacity -= res; graph[graph[u][i].to][graph[u][i].rev].capacity += res; return res; } } } } return 0; } int max_flow(int s, int t) { int flow = 0; vector
    dist(s + 1, -1); while (bfs(s, t)) { vector
    ptr(s + 1, 0); int f = 0; do { f = dfs(s, t, INT_MAX); for (int i = 1; i <= s; ++i) { if (graph[i][0].capacity > 0 && ptr[i] == 0) { ptr[i] = graph[i][0].capacity; } } } while (f > 0); flow += f; } return flow; } int main() { int K, C, M; cin >> K >> C >> M; int total_nodes = K + C; int dist[total_nodes + 1][total_nodes + 1]; for (int i = 1; i <= total_nodes; ++i) { for (int j = 1; j <= total_nodes; ++j) { dist[i][j] = 0; } } int current_node = 0; int current_row = 1; while (true) { string line; if (cin >> line) { size_t len = line.size(); int add = min(len, total_nodes - current_node + 1); for (int i = 0; i < add; ++i) { int val = line[i] - ' '; dist[current_row][current_node] = val; current_node++; if (current_node > total_nodes) { break; } } current_row++; if (current_node > total_nodes) { break; } } else { break; } } for (int i = 1; i <= total_nodes; ++i) { for (int j = 1; j <= total_nodes; ++j) { if (dist[i][j] == 0 && i != j) { dist[i][j] = 0; } } } for (int k = 1; k <= total_nodes; ++k) { for (int i = 1; i <= total_nodes; ++i) { for (int j = 1; j <= total_nodes; ++j) { if (dist[i][k] + dist[k][j] < dist[i][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } int S = 0; int T = total_nodes + 1; int max_distance = 0; for (int i = 1; i <= C; ++i) { for (int j = C + 1; j <= total_nodes; ++j) { if (dist[i][j] > max_distance) { max_distance = dist[i][j]; } } } int l = 0, r = max_distance, ans = max_distance; while (l <= r) { int mid = (l + r) / 2; int size = total_nodes + 2; graph.resize(size, vector
    ()); for (int i = 1; i <= C; ++i) { add_edge(S, i, 1); } for (int i = 1; i <= C; ++i) { for (int j = C + 1; j <= total_nodes; ++j) { if (dist[i][j] <= mid) { add_edge(i, j, 1); } } } for (int j = C + 1; j <= total_nodes; ++j) { add_edge(j, T, M); } int flow = max_flow(S, T); if (flow == C) { ans = mid; r = mid - 1; } else { l = mid + 1; } } cout << ans << endl; }

    代码解释

  • 读取输入:读取挤奶机和牛的数量以及每个挤奶机的容量,然后读取距离矩阵。
  • Floyd-Warshall算法:计算所有节点之间的最短距离。
  • 流网络构建:构建最大流网络,源点连接所有牛,牛连接到挤奶机,挤奶机连接到汇点。
  • 二分搜索优化:使用二分搜索确定最小的最大距离,通过最大流算法检查每个中间值是否可行。
  • 输出结果:打印最小的最大距离。
  • 转载地址:http://wyxfk.baihongyu.com/

    你可能感兴趣的文章
    php,nginx重启
    查看>>
    php:$_ENV 和 getenv区别
    查看>>
    PHP:cURL error 60: SSL certificate unable to get local issuer certificate
    查看>>
    PHP:PDOStatement::bindValue参数类型php5和php7问题
    查看>>
    Q媒体播放器.如何播放具有多个音频的视频?
    查看>>
    pickle
    查看>>
    Pickle thread.lock(Pymongo)
    查看>>
    pickle模块
    查看>>
    qYKVEtqdDg
    查看>>
    pid控制
    查看>>
    PID控制介绍-ChatGPT4o作答
    查看>>
    PID控制器数字化
    查看>>
    Qwen-VL项目使用指南
    查看>>
    PIESDKDoNet二次开发配置注意事项
    查看>>
    PIGS POJ 1149 网络流
    查看>>
    PIL Image对图像进行点乘,加上常数(等像素操作)
    查看>>
    PIL Image转Pytorch Tensor
    查看>>
    PIL&QOOT;IOERROR:带有大图像的图像文件被截断(&Q)
    查看>>
    PIL.Image、cv2的img、bytes相互转换
    查看>>
    PIL.Image进行图像融合显示(Image.blend)
    查看>>