最少路径覆盖 == n - 最大匹配
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<iomanip>
#include<cassert>
using namespace std;
const int maxn = 1011;
const int add = 500;
struct zz
{
int x;
int y;
int z;
}zx[maxn];
vector<int>g[maxn];
int link[maxn];
int use[maxn];
int n;
bool dfs(int now)
{
int to;
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if( !use[to] )
{
use[to] = true;
if(link[to] == -1 || dfs(link[to]) )
{
link[to] = now;
return true;
}
}
}
return false;
}
int matching()
{
int ans = 0;
memset(link,-1,sizeof(link));
memset(use,false,sizeof(use));
for(int i=1;i<=n;i++)
{
memset(use,false,sizeof(use));
if(dfs(i))
{
ans++;
}
}
return ans;
}
bool can(int i,int j)
{
if(zx[i].x < zx[j].x && zx[i].y < zx[j].y && zx[i].z < zx[j].z )
{
return true;
}
return false;
}
int main()
{
while(cin>>n)
{
if(n==0)
{
break;
}
for(int i=1;i<maxn;i++)
{
g[i].clear();
}
for(int i=1;i<=n;i++)
{
cin>>zx[i].x>>zx[i].y>>zx[i].z;
}
int from;
int to;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(can(i,j))
{
from = i;
to = j + add;
g[from].push_back(to);
g[to].push_back(from);
}
}
}
cout<< n - matching()<<endl;
}
return 0;
}