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

来源:互联网 发布:大数据专业相关培训 编辑:程序博客网 时间:2024/05/17 09:24

题意:

n个箱子

下面n行 a b c 表示箱子的长宽高

箱子可以嵌套,里面的箱子三维都要小于外面的箱子

问: 露在外头的箱子有几个

 

思路:

只要成功匹配一条边,就等价于成功嵌套一个箱子,就是匹配一条边,露在外面的箱子就少一个

结果就是 n - 最大匹配数

 

注意一个条件: 箱子不可旋转,即 长对应长, 宽对应宽

然后就是一个裸的二分匹配

 

#include<stdio.h>#include<string.h>#define N 600struct 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;}/*35 4 827 10 10100 32 52331 2 12 1 11 1 241 1 12 3 23 2 24 4 40*/


 

原创粉丝点击