poj 3281 Dining

本文探讨了如何使用最大流算法解决一个有趣的实际问题:如何在考虑每头牛的食物和饮料偏好下,最大化满足牛群饮食需求的数量。通过构建一个特殊的网络流图,该文详细解释了算法实现过程,包括初始化网络、构建边和顶点,以及执行最大流搜索。

题目连接

http://poj.org/problem?id=3281

Dining

Description

Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.

Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.

Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).

Input

Line 1: Three space-separated integers: NF, and D 
Lines 2..N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cow i will eat, and the Di integers following that denote the drinks that cow i will drink.

Output

Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes

Sample Input

4 3 3
2 2 1 2 3 1
2 2 2 3 1 2
2 2 1 3 1 2
2 1 1 3 3

Sample Output

3

最大流,拆点构图。

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using std::min;
using std::sort;
using std::pair;
using std::swap;
using std::queue;
using std::vector;
using std::multimap;
#define pb(e) push_back(e)
#define sz(c) (int)(c).size()
#define mp(a, b) make_pair(a, b)
#define all(c) (c).begin(), (c).end()
#define iter(c) __typeof((c).begin())
#define cls(arr, val) memset(arr, val, sizeof(arr))
#define cpresent(c, e) (find(all(c), (e)) != (c).end())
#define rep(i, n) for(int i = 1; i <= (int)n; i++)
#define tr(c, i) for(iter(c) i = (c).begin(); i != (c).end(); ++i)
const int Max_N = 1100;
const int INF = 0x3f3f3f3f;
struct Ford_Fulkerson {
    struct edge { int to, cap, next, rev; }G[Max_N << 2];
    int  N, F, D, tot, head[Max_N];
    bool vis[Max_N], Food[Max_N][Max_N], Drink[Max_N][Max_N];
    inline void init(int n, int f, int d) {
        tot = 0;
        this->N = n, this->F = f, this->D =d;
        cls(head, -1), cls(Food, false), cls(Drink, false);
    }
    inline void add_edge(int u, int v, int cap = 1) {
        G[tot] = (edge){ v, cap, head[u], tot + 1 }; head[u] = tot++;
        G[tot] = (edge){ u,   0, head[v], tot - 1 }; head[v] = tot++;
    }
    inline void built() {
        int x, y, v;
        rep(i, N) {
            scanf("%d %d", &x, &y);
            while(x--) {
                scanf("%d", &v);
                Food[i][v] = true;
            }
            while(y--) {
                scanf("%d", &v);
                Drink[i][v] = true;
            }
        }
    }
    inline int dfs(int u, int t, int f) {
        if(u == t) return f;
        vis[u] = true;
        for(int i = head[u]; ~i; i = G[i].next) {
            edge &e = G[i];
            if(e.cap > 0 && !vis[e.to]) {
                int d = dfs(e.to, t, min(e.cap, f));
                if(d > 0) {
                    e.cap -= d;
                    G[e.rev].cap +=d;
                    return d;
                }
            }
        }
        return 0;
    }
    inline void max_flow(int s, int t) {
        int flow = 0;
        while(true) {
            cls(vis, false);
            int f = dfs(s, t, INF);
            if(!f) break;
            flow += f;
        }
        printf("%d\n", flow);
    }
    inline void solve() {
        int s = 1, t = s + F + 2 * N + D + 1;
        rep(i, F) {
            add_edge(s, s + i);
        }
        rep(i, D) {
            add_edge(s + F + 2 * N + i, t);
        }
        rep(i, N) {
            add_edge(s + F + i, s + F + N + i, 1);
            rep(j, F) {
                if(Food[i][j]) add_edge(s + j, s + F + i);
            }
            rep(j, D) {
                if(Drink[i][j]) add_edge(s + F + N + i, s + F + 2 * N + j);
            }
        }
        max_flow(s, t);
    }
}go;
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w+", stdout);
#endif
    int n, f, d;
    while(~scanf("%d %d %d", &n, &f, &d)) {
        go.init(n ,f ,d);
        go.built();
        go.solve();
    }
    return 0;
}

转载于:https://www.cnblogs.com/GadyPu/p/4773513.html

内容概要:本文系统阐述了智能物流路径规划的技术体系与实践应用,涵盖其发展背景、核心问题建模、关键算法、多目标与动态环境处理、系统架构及典型应用场景。文章以车辆路径问题(VRP)及其变体为核心数学模型,介绍了从Dijkstra、A*等单智能体算法到多车VRP的元启发式求解方法(如遗传算法、蚁群算法、大规模邻域搜索),并深入探讨了多目标优化(成本、时间、碳排放)与动态环境(实时订单、交通变化)下的自适应规划策略。结合城市配送、干线运输、场内物流等案例,展示了路径规划在提升效率、降低成本方面的实际价值,并分析了当前面临的复杂性、不确定性等挑战,展望了AI融合、数字孪生、车路协同等未来趋势。; 适合人群:具备一定物流、运筹学或计算机基础,从事智能交通、物流调度、算法研发等相关工作的技术人员与管理人员,工作年限1-5年为宜。; 使用场景及目标:①理解智能物流路径规划的整体技术架构与核心算法原理;②掌握VRP建模方法与多目标、动态环境下路径优化的实现策略;③为物流系统设计、算法选型与系统优化提供理论依据与实践参考; 阅读建议:建议结合文中案例与数学模型,重点理解算法选择与实际业务场景的匹配逻辑,关注动态规划与多目标优化的工程实现难点,可配合仿真工具或开源求解器进行实践验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值