当前位置:编程学习 > C/C++ >>

HDU 4160 最小路径覆盖 = 顶点数 - 最大匹配数 二分匹配

题意:
 
n个箱子
 
下面n行 a b c 表示箱子的长宽高
 
箱子可以嵌套,里面的箱子三维都要小于外面的箱子
 
问: 露在外头的箱子有几个
 
 
 
思路:
 
只要成功匹配一条边,就等价于成功嵌套一个箱子,就是匹配一条边,露在外面的箱子就少一个
 
结果就是 n - 最大匹配数
 
 
 
注意一个条件: 箱子不可旋转,即 长对应长, 宽对应宽
 
然后就是一个裸的二分匹配
 
 
 
 
#include<stdio.h>  
#include<string.h>  
  
#define N 600  
  
struct Edge{  
    int to, nex;  
}edge[N*N];  
int head[N*2], edgenum;  
void addedge(int u, int v){  
    Edge E = { v, head[u] };  
    edge[ edgenum ] = E;  
    head[u] = edgenum ++;  
}  
  
struct node{  
    int a,b,c;  
}p[N];  
  
int n;  
  
int lef[N*2];  
bool T[N*2];  
  
int match(int x){  
    for(int i = head[x]; i != -1; i = edge[i].nex){  
        int v = edge[i].to;  
        if(T[v])continue;  
        T[v] = true;  
        if(lef[v] == -1 || match( lef[v] ) )  
        {  
            lef[v] = x;  
            return true;  
        }  
    }  
    return false;  
}  
  
  
int solve(){  
    int ans = 0;  
    memset(lef, -1, sizeof(lef));  
    for(int i = 1; i <= n; i++)  
    {  
        memset(T, 0, sizeof(T));  
        ans += match( i );  
    }  
    return ans;  
}  
  
void init(){  
    memset(head, -1, sizeof(head)),     edgenum = 0;  
  
    for(int i = 1; i <= n; i++)  
        scanf("%d %d %d", &p[i].a, &p[i].b, &p[i].c);  
  
    for(int i = 1; i <= n; i++)  
        for(int j = 1; j <= n; j++)  
        {  
            if(p[i].a < p[j].a && p[i].b < p[j].b && p[i].c < p[j].c)  
                addedge(i, j + N);  
        }  
}  
  
int main(){  
    int  m, u, v;  
    while(~scanf("%d",&n), n){  
        init();  
        printf("%d\n", n - solve());  
    }  
    return 0;  
}  
/* 
3 
5 4 8 
27 10 10 
100 32 523 
3 
1 2 1 
2 1 1 
1 1 2 
4 
1 1 1 
2 3 2 
3 2 2 
4 4 4 

0 

*/  

 

 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,