• 【luogu P2762 太空飞行计划问题】 题解


    题目链接:https://www.luogu.org/problemnew/show/P2762
    算是拍照那个题的加强下。

    输入真的很毒瘤。(都这么说但好像我的过了?

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 1e6 + 10;
    const int inf = 1e9;
    ll n, m, s, t, deep[maxn], maxflow, w[maxn], ans;
    struct edge{
        ll next, to, flow;
    }e[maxn<<2];
    ll head[maxn], cnt = -1;
    queue<ll> q;
    void add(ll u, ll v, ll w)
    {
        e[++cnt].flow = w; e[cnt].next = head[u]; e[cnt].to = v; head[u] = cnt;
        e[++cnt].flow = 0; e[cnt].next = head[v]; e[cnt].to = u; head[v] = cnt;
    }
    bool bfs(ll s, ll t)
    {
        memset(deep, 0x7f, sizeof(deep));
        while(!q.empty()) q.pop();
        q.push(s); deep[s] = 0;
        while(!q.empty())
        {
            ll now = q.front(); q.pop();
            for(ll i = head[now]; i != -1; i = e[i].next)
            {
                if(deep[e[i].to] > inf && e[i].flow)
                {
                    deep[e[i].to] = deep[now] + 1;
                    q.push(e[i].to);
                }
            }
        }
        if(deep[t] < inf) return true;
        else return false;
    }
    ll dfs(ll now, ll t, ll limit)
    {
        if(!limit || now == t) return limit;
        ll flow = 0, f;
        for(ll i = head[now]; i != -1; i = e[i].next)
        {
            if(deep[e[i].to] == deep[now] + 1 && (f = dfs(e[i].to, t, min(e[i].flow, limit))))
            {
                flow += f;
                limit -= f;
                e[i].flow -= f;
                e[i^1].flow += f;
                if(!limit) break;
            }
        }
        return flow;
    }
    void Dinic(ll s, ll t)
    {
        while(bfs(s, t))
        maxflow += dfs(s, t, inf);
    }
    int main()
    {
        memset(head, -1, sizeof(head));
        scanf("%lld%lldd",&m,&n);
        s = 1, t = 2 + n + m;
        for(ll i = 1; i <= m; i++)
        {
            ll u;
            scanf("%lld",&w[i]);
            ans += w[i];
            while(scanf("%lld",&u))
            {
                add(i + n + 1, u + 1, inf);
                if(getchar() == '
    ') break;
            }
        }
        for(ll i = 1; i <= n; i++)
        {
            ll c;
            scanf("%lld",&c);
            add(i + 1, t, c);
        }
        for(ll i = 1; i <= m; i++)
        {
            add(s, i + n + 1, w[i]);
        }
        Dinic(s, t);
        for(ll i = 1; i <= m; i++)
        if(deep[i + 1 + n] < inf) printf("%lld ",i); 
        printf("
    ");
        for(ll i = 1; i <= n; i++)
        if(deep[i + 1] < inf) printf("%lld ",i); 
        printf("
    ");
        printf("%lld",ans - maxflow);
        return 0;
    }
    
  • 相关阅读:
    2019南昌网络赛-I(单调栈+线段树)
    poj3250(单调栈模板题)
    poj2528(线段树+离散化)
    poj2828(线段树查找序列第k小的值)
    Seikimatsu Occult Tonneru(网络流,状态数(建不建边)不多时,可考虑直接进行枚举
    A. Coffee Break(思维题,类似于邻接表的head数组用法)
    E. Paint the Tree(树形dp)
    cdq分治学习
    2018SEERC Points and Rectangles (CDQ分治)
    SEERC 2018 Inversion
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/9447490.html
Copyright © 2020-2023  润新知