[Simple Explanation] SP7556 Stock Charts

Subject to the effect

Gives a line chart, there are N segments, you want to set these into several segments, each set such that any two line segments do not intersect.

It requires at least a set of numbers.

analysis

Meow Pass : all folding lines mentioned below refer to the abscissa \ ([1, k] \ ) in the polylines.

If the intersection of two fold line thinking what would happen?

Yes, that is, one on one below (how strange it).

For example, polylines \ (a \) on, line \ (b \) in the next, all attempts to satisfy this relationship polyline even a tuple \ (a \) to \ (b \) is directed edges, we can find using a collection can follow a path, then find the minimum number set of topics that go seek the path of least, all the division points were all covered.
This question then is converted to the minimum path cover problem , assuming you would have this problem, then that is loved by the Hungarian template time friends ~

will not?

Sweet dreams.

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 200 + 5;
const int M = 10000 + 5;

inline int read(){
    int f = 1, x = 0; char ch;
    do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
    do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); 
    return f * x;
}

inline void write(int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

inline int max(int a, int b) { return a < b ? b : a; }

inline int min(int a, int b) { return a < b ? a : b; }

struct Graph {
    int to[M << 1], nxt[M << 1], head[N], cnt;
    inline void add(int x, int y) {
        ++cnt;
        to[cnt] = y, nxt[cnt] = head[x], head[x] = cnt;
        return;
    }
}G;
int t, n, k, price[N][30], op, tot;
int vis[N], match[N], bj[N];
inline bool dfs(int u) {
    for (int i = G.head[u];i;i = G.nxt[i]) {
        int v = G.to[i];
        if (!vis[v]) {
            vis[v] = 1;
            if (!match[v] || dfs(match[v])) {
                match[v] = u, bj[u] = v;
                return 1;
            }
        }
    }
    return 0;
}

int rate[N];
inline bool cmp(const int &x, const int &y) {
    return price[x][0] > price[y][0];
}

inline bool can(int u, int v) {
    for (int i = 1;i <= k; ++i) {
        if (price[u][i] <= price[v][i]) return 0;
    }
    return 1;
}

int main(){
//  freopen("in.txt", "r", stdin);
//  freopen("out.txt", "w", stdout);
    t = read();
    while (t --) {
        n = read(), k = read();
        memset(bj, 0, sizeof bj);
        memset(G.head, 0, sizeof G.head);
        memset(match, 0, sizeof match);
        memset(price, 0, sizeof price);
        G.cnt = 0;
        for (int i = 1;i <= n; ++i) {
            for (int j = 1;j <= k; ++j) {
                price[i][j] = read();
                price[i][0] = max(price[i][0], price[i][j]);
            }
            rate[i] = i;
        }

        std :: sort(rate + 1, rate + 1 + n, cmp);

        for (int i = 1, u;i <= n; ++i) {
            u = rate[i];
            for (int j = i + 1, v;j <= n; ++j) {
                v = rate[j];
                if (can(u, v)) G.add(u, v);
            }
        }

        tot = 0;
        for (int i = 1;i <= n; ++i) {
            if (bj[i] == 0) {
                memset(vis, 0, sizeof vis);
                if (dfs(i)) tot ++;
            }
        }
        printf("Case #%d: %d\n", ++op, n - tot);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/silentEAG/p/11732662.html