http://acm.hdu.edu.cn/showproblem.php?pid=4160
转化为二分图的最小路径覆盖问题。
那么答案就是n-最大匹配数
View Code
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<vector> #define maxn 10000 using namespace std; int n; struct node0 { int h,w,l; }node[maxn]; vector<int>point[maxn]; int visit[maxn]; int mm[maxn]; void init() { for(int i=0;i<=2*n;i++) point[i].clear(); for(int i=0;i<n;i++) cin>>node[i].w>>node[i].l>>node[i].h; } int check(int a,int b) { if(node[a].w<node[b].w&&node[a].h<node[b].h&&node[a].l<node[b].l) return 1; return 0; } void build() { for(int i=0;i<n;i++)//经典连边,分成i与i‘点 for(int j=0;j<n;j++) if(check(i,j))point[i].push_back(j);//能够放下,连边 } int dfs(int fa) { for(int i=0;i<point[fa].size();i++)//对于每一个连的点 { if(!visit[point[fa][i]])//如果还没访问 { visit[point[fa][i]]=1; if(mm[point[fa][i]]==-1||dfs(mm[point[fa][i]]))//在没访问的前提 //下,如果改点还没匹配,或者他的父亲有还没匹配的点 { mm[point[fa][i]]=fa; return 1; } } } return 0; } void solve() { int cnt=0; memset(mm,-1,sizeof(mm));//初始化都不在匹配图中 for(int i=0;i<n;i++) { memset(visit,0,sizeof(visit));//每一次深搜初始化,都没有访问过 if(dfs(i))cnt++;//dfs找增广路 } cout<<n-cnt<<endl; } int main() { while((cin>>n)&&n) { init(); build(); solve(); } return 0; }