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++ ,