link:点击打开链接
有向无环图的最小路径覆盖
结论:点击打开链接
原来unique之前要先排序,坑了
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define sqr(a) (a)*(a)
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,n,m) for(int i=n;i>=m;i--)
#define lan(a,b) memset(a,b,sizeof(a))
#define maxn 1010
using namespace std;
int useif[maxn]; ///记录y中节点是否使用 0表示没有访问过,1为访问过
int link[maxn]; ///记录当前与y节点相连的x的节点
int mat[maxn][maxn]; ///记录连接x和y的边,如果i和j之间有边则为1,否则为0
int gn,gm; ///二分图中x和y中点的数目
int can(int t)
{
int i;
for(i=1;i<=gm;i++)
{
if(useif[i]==0 && mat[t][i])
{
useif[i]=1;
if(link[i]==-1 || can(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int i,num;
num=0;
lan(link,-1);
for(i=1;i<=gn;i++)
{
memset(useif,0,sizeof(useif));
if(can(i)) num++;
}
return num;
}
int main()
{
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
int n;
while(~scanf("%d",&n))
{
lan(mat,0);
int a[1010];
For(i,1,n)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-(a+1);
if(n==1)
{
printf("1\n");
continue;
}
For(i,1,n)
{
For(j,1,i-1)
{
if(a[i]%a[j]==0)
{
mat[i][j]=1;
}
}
}
gn=gm=n;
int ans=MaxMatch();
printf("%d\n",n-ans);
}
return 0;
}