hdoj 4160 Dolls

来源:互联网 发布:手机淘宝借贷怎么借钱 编辑:程序博客网 时间:2024/06/03 18:16

类型:二分图

如果将每个doll看做一个节点,对于xi < xj & yi < yj & zi < zj 构造一条有向边,则题目要求的即是图的最小路径覆盖

最小路径覆盖和二分图的最大匹配的关系是:最小路径覆盖 = |P|-最大匹配数

所以可转化为求二分图的最大匹配问题

使用匈牙利算法求解,不断寻找增光路,获得更大的匹配

// hdoj 4160 Dolls#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n;int result[510]; bool state [510]; bool data[510][510];struct node {    int x, y, z;}p[510];bool i_less_j(int a, int b) {    if(p[a].x < p[b].x && p[a].y < p[b].y && p[a].z < p[b].z)        return true;    return false;}bool find(int a) {    int i;    for (i = 1; i <= n; i++) {        if (data[a][i] == true && !state[i]) {            state[i] = true;            if (result[i] == 0 || find(result[i])) {                result[i] = a;                 return true;             }        }    }    return false;}bool cmp(node b,node c){if(b.x < c.x)        return true;if(b.x == c.x && b.y < c.y)        return true;if(b.x == c.x && b.y == c.y && b.z < c.z)        return true;return false;}void solve() {    int i, j;    while(scanf("%d", &n), n) {        memset(data, false, sizeof(data));        memset(result, 0, sizeof(result));        int ans = 0;        for(i = 1; i <= n; ++i)            scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z);        sort(p + 1, p + n + 1, cmp);        for(i = 1; i < n; ++i)        for(j = i + 1; j <= n; ++j) {            if(i_less_j(i, j))                data[i][j] = true;        }        for(i = 1; i <= n; ++i) {            memset(state, false, sizeof(state));            if(find(i))                ++ans;        }        printf("%d\n", n - ans);    }    return;}int main() {    solve();    return 0;}



原创粉丝点击