P3358 最长k可重区间集问题

Posted albert-biu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3358 最长k可重区间集问题相关的知识,希望对你有一定的参考价值。

P3358 最长k可重区间集问题

题目链接

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> P;

struct edge 
    int to, cap, cost, rev;

    edge(int a, int b, int c, int d)
            : to(a), cap(b), cost(c), rev(d) 
;

const int maxn = 510;
const int maxv = maxn * 2;
const int inf = 0x3f3f3f3f;

int cas;
int n, k, m;
int A[maxn], B[maxn], C[maxn];
vector<int> X;

vector<edge> G[maxv];
int dis0[maxv], dis1[maxv];
int pv[maxv], pe[maxv];

void add(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));


//迪杰斯特拉算法求最短路
void dijkstra(int s) 
    memset(dis1, inf, sizeof dis1);
    dis1[s] = 0;
    priority_queue<P, vector<P>, greater<P> > qu;
    qu.push(P(0, s));

    while (qu.size()) 
        P p = qu.top();
        qu.pop();
        int v = p.second;
        if (dis1[v] < p.first) continue;

        for (int i = 0; i < G[v].size(); i++) 
            edge e = G[v][i];
            if (e.cap > 0 && dis1[e.to] > dis1[v] + e.cost + dis0[v] - dis0[e.to]) 
                dis1[e.to] = dis1[v] + e.cost + dis0[v] - dis0[e.to];
                pv[e.to] = v;
                pe[e.to] = i;
                qu.push(P(dis1[e.to], e.to));
            
        
    


//最小费用流算法
int min_cost_flow(int s, int t, int f) 
    int res = 0;
    memset(dis0, 0, sizeof dis0);

    while (f > 0) 
        dijkstra(s);

        if (dis1[t] == inf) return -1;

        for (int i = s; i <= t; i++)
            dis0[i] += dis1[i];

        int d = f;
        for (int v = t; v != s; v = pv[v])
            d = min(d, G[pv[v]][pe[v]].cap);

        f -= d;
        res += d * dis0[t];

        for (int v = t; v != s; v = pv[v]) 
            edge &e = G[pv[v]][pe[v]];
            e.cap -= d;
            G[e.to][e.rev].cap += d;
        
    

    return res;


int main() 
    X.clear();
    for (int i = 0; i < maxv; i++)
        G[i].clear();

    cin >> n >> k;

    for (int i = 0; i < n; i++) 
        cin >> A[i] >> B[i];
        C[i] = B[i] - A[i];
        X.push_back(A[i]);
        X.push_back(B[i]);
    


    //离散化
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());

    int s = 0, t = X.size() - 1;

    for (int i = 0; i < t; i++)
        add(i, i + 1, inf, 0);

    for (int i = 0; i < n; i++) 
        int a = lower_bound(X.begin(), X.end(), A[i]) - X.begin();
        int b = lower_bound(X.begin(), X.end(), B[i]) - X.begin();
        add(a, b, 1, -C[i]);
    

    cout << -min_cost_flow(s, t, k) << endl;
    return 0;

以上是关于P3358 最长k可重区间集问题的主要内容,如果未能解决你的问题,请参考以下文章

P3358 最长k可重区间集问题

luogu P3358 最长k可重区间集问题

最长k可重区间集

最长k可重区间集问题

最长k可重区间集(cogs 743)

网络流24题21最长k可重区间集问题