2019HDU multi-school third K subsequence-- minimum cost maximum flow

The meaning of problems

A given number of columns n-$ $ integers, which select at most one up $ k $ sequence (up to one element selected once), and such that the maximum element selected.

analysis

Consider this classic problem and network flow problem "is not the longest drop sequence" similarity, we consider this to build a network diagram and flow resolved. Because it seeks costs and expenses flow approach is used.

Specific construction diagram, see the code, the main point to consider demolition and building super super source and the sink.

(Then SPFA version times out, replaced by Dijkstra version

#include<bits/stdc++.h>
using namespace std;
#define il inline

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 4000 + 10;
int n, k, a[maxn];

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, intcost) { 
        G [ from ] .push_back (Edge (to, CAP, cost, G [to] .size ())); 
        G [to] .push_back (Edge ( from , 0 , -cost, G [ from ]. size () - . 1 )); 
    } 
    // flow into their own variable transmission, that is, the last maximum flow, the minimum cost of return 
    int Min_cost_max_flow ( int S, int T, int F, int & flow) {
         int RES = 0 ; Fill (H, H + . 1 + V, 0 );
         the while (F) { 
            The 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;
            }
        }
        returnRES; 
    } 
} MCMF; 

void Solve () 
{ 
    mcmf.Init ( 2 * n-+ . 3 );
     for ( int I = . 1 ; I <= n-; I ++ ) 
    { 
        mcmf.Add_Edge (I, I + n-, . 1 , - A [I]);
         for ( int J = I + . 1 ; J <= n-; J ++ ) 
        { 
            IF (A [J]> = A [I]) 
            { 
                mcmf.Add_Edge (I + n-, J, . 1 , 0 ); // should be even greater than the right of each side
                 //BREAK; 
            } 
        } 
    } 
    mcmf.Add_Edge ( 2 * n-+ . 1 , 2 * n-+ 2 , K, 0 );
     for ( int I = . 1 ; I <= n-; I ++) mcmf.Add_Edge ( 2 * n-+ 2 , I, . 1 , 0 );   // Create super source. 1 + 2N 
    for ( int I = . 1 ; I <= n-; I ++) mcmf.Add_Edge (n-I +, 2 * n-+ . 3 , . 1 , 0 );      // Create super sinks point 2 + 2N 
    int flow = 0;
    int ans = mcmf.Min_cost_max_flow(2*n+1, 2*n+3, INF, flow);
    printf("%d\n", -ans);
}

int main()
{
//    freopen("multi.in", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &k);
        for(int i = 1;i <= n;i++)  scanf("%d", &a[i]);
        solve();
    }
}

 

Guess you like

Origin www.cnblogs.com/lfri/p/11267070.html