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;
}
posted on 2012-08-28 20:17  一把刷子  阅读(145)  评论(0编辑  收藏  举报