zoukankan      html  css  js  c++  java
  • P4452 [国家集训队]航班安排(最大费用最大流)

    P4452 [国家集训队]航班安排

    题目传送门

    解题思路:

    感觉题面让人有很多误解,就是说有k架飞机在0点从0号机场起飞,在t时刻返回机场,给出空载飞行的时间和花费以及m个包机请求的花费和起始时间和终止时间,想要得到净利润最大,显然是个费用流,对于每个询问拆成两个点,点之间连一条流量为1,花费为这次请求的c,由于从0号机场起飞,如果满足0+从0号机场飞到该次请求的机场a的时间<=请求任务开始的时间s,那么建一条流量为inf,费用为-从0号机场飞到该次请求的机场a的花费,同样如果满足该次请求的t+该次请求的b机场飞到0号机场的时间<=t,也建一条流量为inf,费用为-从该次请求的b号机场飞到0号机场的花费,最后对于每个询问,是否能与其他询问连边,如果一个询问的结束时间t+从该询问的b机场到另一个询问的a机场的时间<=另一个询问的开始时间s,那么也能连上一条流量为inf,花费为-空载飞行的花费的边,最后由于有k架飞机,再建个超级源点流到0号机场的点,流量为k,花费为0即可

    代码:

    代码写得和解题思路有点出入,主要是点位序号我为了方便把0号机场变成了1号

    #include <bits/stdc++.h>
    using namespace std;
    /*    freopen("k.in", "r", stdin);
        freopen("k.out", "w", stdout); */
    // clock_t c1 = clock();
    // std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #define de(a) cout << #a << " = " << a << endl
    #define rep(i, a, n) for (int i = a; i <= n; i++)
    #define per(i, a, n) for (int i = n; i >= a; i--)
    #define ls ((x) << 1)
    #define rs ((x) << 1 | 1)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    typedef vector<int, int> VII;
    #define inf 0x3f3f3f3f
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MAXN = 1e5 + 7;
    const ll MAXM = 1e6 + 7;
    const ll MOD = 1e9 + 7;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    inline int read_int()
    {
        char c;
        int ret = 0, sgn = 1;
        do
        {
            c = getchar();
        } while ((c < '0' || c > '9') && c != '-');
        if (c == '-')
            sgn = -1;
        else
            ret = c - '0';
        while ((c = getchar()) >= '0' && c <= '9')
            ret = ret * 10 + (c - '0');
        return sgn * ret;
    }
    inline ll read_ll()
    {
        char c;
        ll ret = 0, sgn = 1;
        do
        {
            c = getchar();
        } while ((c < '0' || c > '9') && c != '-');
        if (c == '-')
            sgn = -1;
        else
            ret = c - '0';
        while ((c = getchar()) >= '0' && c <= '9')
            ret = ret * 10 + (c - '0');
        return sgn * ret;
    }
    
    struct edge
    {
        int to, capacity, cost, rev;
        edge() {}
        edge(int to, int _capacity, int _cost, int _rev) : to(to), capacity(_capacity), cost(_cost), rev(_rev) {}
    };
    struct Min_Cost_Max_Flow
    {
        int V, H[MAXN + 5], dis[MAXN + 5], PreV[MAXN + 5], PreE[MAXN + 5];
        vector<edge> G[MAXN + 5];
        void Init(int n)
        {
            V = n;
            for (int i = 0; i <= V; ++i)
                G[i].clear();
        }
        void Add_Edge(int from, int to, int cap, int cost)
        {
            G[from].push_back(edge(to, cap, cost, G[to].size()));
            G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
        }
        int Min_cost_max_flow(int s, int t, int f, int &flow) 
        {
            int res = 0;
            fill(H, H + 1 + V, 0);
            while (f)
            {
                priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
                fill(dis, dis + 1 + V, inf);
                dis[s] = 0;
                q.push(pair<int, int>(0, s));
                while (!q.empty())
                {
                    pair<int, int> now = q.top();
                    q.pop();
                    int v = now.second;
                    if (dis[v] < now.first)
                        continue;
                    for (int i = 0; i < G[v].size(); ++i)
                    {
                        edge &e = G[v][i];
                        if (e.capacity > 0 && dis[e.to] > dis[v] + e.cost + H[v] - H[e.to])
                        {
                            dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
                            PreV[e.to] = v;
                            PreE[e.to] = i;
                            q.push(pair<int, int>(dis[e.to], e.to));
                        }
                    }
                }
                if (dis[t] == inf)
                    break;
                for (int i = 0; i <= V; ++i)
                    H[i] += dis[i];
                int d = f;
                for (int v = t; v != s; v = PreV[v])
                    d = min(d, G[PreV[v]][PreE[v]].capacity);
                f -= d;
                flow += d;
                res += d * H[t];
                for (int v = t; v != s; v = PreV[v])
                {
                    edge &e = G[PreV[v]][PreE[v]];
                    e.capacity -= d;
                    G[v][e.rev].capacity += d;
                }
            }
            return res;
        }
        int Max_cost_max_flow(int s, int t, int f, int &flow)
        {
            int res = 0;
            fill(H, H + 1 + V, 0);
            while (f)
            {
                priority_queue<pair<int, int>> q;
                fill(dis, dis + 1 + V, -inf);
                dis[s] = 0;
                q.push(pair<int, int>(0, s));
                while (!q.empty())
                {
                    pair<int, int> now = q.top();
                    q.pop();
                    int v = now.second;
                    if (dis[v] > now.first)
                        continue;
                    for (int i = 0; i < G[v].size(); ++i)
                    {
                        edge &e = G[v][i];
                        if (e.capacity > 0 && dis[e.to] < dis[v] + e.cost + H[v] - H[e.to])
                        {
                            dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
                            PreV[e.to] = v;
                            PreE[e.to] = i;
                            q.push(pair<int, int>(dis[e.to], e.to));
                        }
                    }
                }
                if (dis[t] == -inf)
                    break;
                for (int i = 0; i <= V; ++i)
                    H[i] += dis[i];
                int d = f;
                for (int v = t; v != s; v = PreV[v])
                    d = min(d, G[PreV[v]][PreE[v]].capacity);
                f -= d;
                flow += d;
                res += d * H[t];
                for (int v = t; v != s; v = PreV[v])
                {
                    edge &e = G[PreV[v]][PreE[v]];
                    e.capacity -= d;
                    G[v][e.rev].capacity += d;
                }
            }
            return res;
        }
    };
    Min_Cost_Max_Flow MCMF;
    PII p[305][305];
    struct quest
    {
        int a, b, s, t, c;
    } q[MAXN + 5];
    int main()
    {
        int n = read_int(), m = read_int(), k = read_int(), t = read_int();
        MCMF.Init((m << 1 | 1) + 1);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                p[i][j].first = read_int();
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                p[i][j].second = read_int();
        for (int i = 1; i <= m; i++)
        {
            q[i].a = read_int(), q[i].b = read_int(), q[i].s = read_int(), q[i].t = read_int(), q[i].c = read_int();
            q[i].a++, q[i].b++;
        }
        for (int i = 1; i <= m; i++)
        {
            MCMF.Add_Edge(i << 1, i << 1 | 1, 1, q[i].c);
            if (p[1][q[i].a].first <= q[i].s)
                MCMF.Add_Edge(1, i << 1, inf, -p[1][q[i].a].second);
            if (p[q[i].b][1].first + q[i].t <= t)
                MCMF.Add_Edge(i << 1 | 1, (m << 1 | 1) + 1, inf, -p[q[i].b][1].second);
            for (int j = 1; j <= m; j++)
            {
                if (i == j)
                    continue;
                if (q[i].t + p[q[i].b][q[j].a].first <= q[j].s)
                    MCMF.Add_Edge(i << 1 | 1, j << 1, inf, -p[q[i].b][q[j].a].second);
            }
        }
        int st = 0, ed = (m << 1 | 1) + 1;
        MCMF.Add_Edge(st, 1, k, 0);
        int flow = 0;
        int ans = MCMF.Max_cost_max_flow(st, ed, inf, flow);
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    二叉查找树
    二叉树
    广度优先搜索
    深度优先搜索
    algorithm:next_permutation
    Grafana Labs 携手阿里云,将提供国内首款 Grafana 托管服务
    台积电TSMC一些技术特点
    TSMC台积电各种制程工艺技术
    激光雷达激烈竞争市场
    边端云处理器系列技术参数
  • 原文地址:https://www.cnblogs.com/graytido/p/12000812.html
Copyright © 2011-2022 走看看