博客
关于我
POJ 2391 多源多汇拆点最大流 +flody+二分答案
阅读量:804 次
发布时间:2023-03-03

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

为了解决牛避雨的问题,我们需要构建一个图模型,其中每个点代表一个顶点,具有当前牛的数量和雨棚的容量。牛们可以从多个源点出发,移动到多个汇点,目标是找到最短的时间使所有牛都能避雨。

模型构建

  • 超级源点和超级汇点

    • 超级源点连接所有点,容量为该点的当前牛数量。
    • 超级汇点连接所有点,容量为该点雨棚的容量。
  • 边的容量

    • 源点到汇点的边容量为0。
    • 点之间的边容量为无穷大,表示可以直接移动。
  • Dinic算法

    • 使用Dinic算法求解多源到多汇的最大流问题,找到最短的时间。
  • 代码实现

    import sysfrom collections import dequedef main():    n = int(sys.stdin.readline())    m = int(sys.stdin.readline())    cow = [0] * (n + 1)    shelter = [0] * (n + 1)    num_cows = 0    sh = 0    for i in range(1, n + 1):        a, b = map(int, sys.stdin.readline().split())        cow[i] = a        shelter[i] = b        num_cows += a    INF = 1 << 60    max_flow = 0    level = [0] * (2 * n + 2)    vis = [False] * (2 * n + 2)    head = [-1] * (2 * n + 2)    size = 2 * n + 2    def bfs(s, t):        queue = deque()        vis[s] = True        level[s] = 0        queue.append(s)        while queue:            u = queue.popleft()            if u == t:                return True            for i in range(head[u], -1, -1):                v = e[i][0]                if not vis[v]:                    vis[v] = True                    level[v] = level[u] + 1                    queue.append(v)                    if v == t:                        return True            head[u] = -1    def dfs(u, flow):        if u == t:            return flow        while head[u] != -1:            v = e[head[u]][0]            if level[v] == level[u] + 1 and e[head[u]][2] > 0:                min_flow = min(flow, e[head[u]][2])                res = dfs(v, min_flow)                if res > 0:                    e[head[u]][2] -= res                    e[head[u] + 1][2] += res                    return res            head[u] = e[head[u] + 1][0]        return 0    e = [[] for _ in range(size * 2)]    head = [-1] * size    def add_edge(u, v, cap):        e[u].append((v, cap))        e[v].append((u, 0))    def bfs_level():        queue = deque()        vis = [False] * size        level = [0] * size        queue.append(0)        vis[0] = True        while queue:            u = queue.popleft()            for (v, _) in e[u]:                if not vis[v]:                    vis[v] = True                    level[v] = level[u] + 1                    queue.append(v)                    if v == t:                        return True        return False    def dfs_flow(u, flow):        if u == t:            return flow        while head[u] != -1:            v = e[head[u]][0]            if level[v] == level[u] + 1 and e[head[u]][2] > 0:                min_flow = min(flow, e[head[u]][2])                res = dfs_flow(v, min_flow)                if res > 0:                    e[head[u]][2] -= res                    e[head[u] + 1][2] += res                    return res            head[u] = e[head[u] + 1][0]        return 0    t = n + 1    for i in range(1, n + 1):        add_edge(0, i, cow[i])        add_edge(i, t, shelter[i])        for j in range(1, n + 1):            if shelter[i] > 0 and shelter[j] > 0:                add_edge(i, j, INF)                add_edge(j, i, INF)    while True:        level = [0] * size        vis = [False] * size        q = deque()        q.append(0)        vis[0] = True        while q:            u = q.popleft()            if u == t:                break            for (v, cap) in e[u]:                if not vis[v]:                    vis[v] = True                    level[v] = level[u] + 1                    q.append(v)        if vis[t]:            break        head = [-1] * size        while True:            u = t            flow = 0            while u != 0:                v = e[head[u]][0]                if level[v] == level[u] + 1 and e[head[u]][2] > 0:                    min_flow = min(flow, e[head[u]][2])                    res = dfs_flow(v, min_flow)                    if res > 0:                        flow += res                        e[head[u]][2] -= res                        e[head[u] + 1][2] += res                        u = v                    else:                        break                head[u] = e[head[u] + 1][0]                u = e[head[u]][0]            if flow > max_flow:                max_flow = flow            level = [0] * size            vis = [False] * size            q = deque()            q.append(0)            vis[0] = True            while q:                u = q.popleft()                for (v, cap) in e[u]:                    if not vis[v]:                        vis[v] = True                        level[v] = level[u] + 1                        q.append(v)                if u == t:                    break        if max_flow == num_cows:            break    print(max_flow)if __name__ == "__main__":    main()

    代码解释

  • 输入处理:读取输入数据,初始化牛的数量和雨棚容量。
  • 超级源点和超级汇点:构建超级源点(0)连接所有点,容量为牛的数量;超级汇点(n+1)连接所有点,容量为雨棚容量。
  • 图的构建:添加点之间的无限容量边,以及源点和汇点的有限容量边。
  • BFS和DFS:使用BFS计算层次,DFS计算最大流。
  • 二分法:检查不同时间点的最大流,找到最小的最大时间。
  • 通过上述步骤,可以高效地解决牛避雨问题,确保所有牛在最短时间内安全到达。

    转载地址:http://pyxfk.baihongyu.com/

    你可能感兴趣的文章
    python | Python集成学习和随机森林算法
    查看>>
    python | Python高阶函数与函数式编程
    查看>>
    python | pytime,一个实用的 时间和日期处理 Python 库!
    查看>>
    python | pyupgrade,一个有趣的 Python 库!
    查看>>
    python | pyvips,一个神奇的 图像处理 Python 库
    查看>>
    Python | qutip,一个高级的 Python 库!
    查看>>
    python | rapidjson,一个实用的 提高JSON处理效率 Python 库!
    查看>>
    python | reflex,一个无敌的 Python 库!
    查看>>
    python | reloading,一个强大的 Python 库!
    查看>>
    python | rich,一个无敌的 Python 库!
    查看>>
    python | rlax,一个超强的 强化学习领域 Python 库!
    查看>>
    python | rpyc,一个超实用的 Python 库!
    查看>>
    python | rq,一个无敌的 关于Redis 的Python 库!
    查看>>
    python读取字符串指定位置字符_python要怎么截取指定位置的字符串呢?
    查看>>
    python | scikit-llm,一个神奇的 Python 库!
    查看>>
    python | sentry,一个超酷的 关于错误监控工具 Python 库!
    查看>>
    python | shiv,一个超酷的 打包工具 Python 库!
    查看>>
    python | six,一个神奇的 Python 库!
    查看>>
    Python读取图片的几种方法供net使用
    查看>>
    python | spacy,一个神奇的 Python 库!
    查看>>