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;

}

 

你可能感兴趣的:(visibility)