hdu 3335 Divisibility

最小路径覆盖

先把相同的数字去掉即去重,按整除或者被整除关系建立有向图,可知这个有向图一定是无环的(DAG),转化为最小路径覆盖模型

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 1010

bool vis[MAX];
int mat[MAX];
long long a[MAX];
int first[MAX];
struct edge
{
   int u,v,next;
}e[MAX*MAX];
int nume;

void add(int u , int v)
{
   e[nume].u=u; e[nume].v=v;
   e[nume].next=first[u]; first[u]=nume++;
}

bool dfs(int u)
{
   for(int k=first[u]; k!=-1; k=e[k].next)
      if(!vis[e[k].v])
      {
         int v=e[k].v;
         vis[v]=true;
         if(mat[v]==-1 || dfs(mat[v]))
         {
            mat[v]=u;
            return true;
         }
      }
   return false;
}

int main()
{
   int T,n;
   scanf("%d",&T);
   while(T--)
   {
      scanf("%d",&n);
      for(int i=1; i<=n; i++)
         scanf("%I64d",&a[i]);
      sort(a+1,a+n+1);
      int m=1;
      for(int i=2; i<=n; i++)
         if(a[i]!=a[i-1])
            a[++m]=a[i];
      n=m;

      nume=0;
      memset(first,-1,sizeof(first));
      for(int i=1; i<=n; i++)
         for(int j=1; j<=n; j++)
            if(i!=j && !(a[i]%a[j]))
             add(i,j);

      memset(mat,-1,sizeof(mat));
      int ccount=0;
      for(int i=1; i<=n; i++)
      {
         memset(vis,false,sizeof(vis));
         if(dfs(i))
            ccount++;
      }
      printf("%d\n",n-ccount);
   }
   return 0;
}

 

posted @ 2013-03-23 12:33  Titanium  阅读(247)  评论(0编辑  收藏  举报