最小路径覆盖
先把相同的数字去掉即去重,按整除或者被整除关系建立有向图,可知这个有向图一定是无环的(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; }