题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3335
题解:从中选出最多的数能够使得其两两之间不能整除
#include <stdio.h>
#include <string.h>
#define MAXN 1001
int n,graphics[MAXN][MAXN],used[MAXN];
_int64 from[MAXN],num[MAXN];
//二分图的最小路径覆盖=|N|-最大匹配数
int find(int x)
{
int i;
for(i=0;i<n;++i)
{
if(!used[i]&&graphics[x][i])
{
used[i]=1;
if(from[i]==-1||find(from[i]))
{
from[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int test,i,j,ans;
scanf("%d",&test);
while(test--)
{
memset(graphics,0,sizeof(graphics));
memset(from,-1,sizeof(from));
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%I64d",&num[i]);
for(j=0;j<i;++j)
if(num[i]%num[j]==0||num[j]%num[i]==0)
graphics[i][j]=1;
}
ans=0;
for(i=0;i<n;++i)
{
memset(used,0,sizeof(used));
if(find(i))
ans++;
}
printf("%d\n",n-ans);
}
return 0;
}
//转BFS
#include <algorithm>
using namespace std;
__int64 a[1005],b[1005];
int t,n,i,j,k,temp;
void BFS(int x)
{
b[x]=0;
for(k=x+1;k<n;k++)
{
if(a[k]%a[x]==0)
{
BFS(k);
break;
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
temp=0;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%I64d",&a[i]);
sort(a,a+n);
for(i=0;i<n;i++)
b[i]=1;
for(i=0;i<n;i++)
{
if(b[i]==1)
{
temp++;
BFS(i);
}
}
printf("%d\n",temp);
}
return 0;
}