题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3335
思路:有矛盾的条件一般都应该往匹配这方面想:
能够整除的连边,于是答案(最小路径)==|顶点个数|-最大匹配。这儿要注意的地方就是要去掉相同的数(排序一下即可),然后就是hungry算法搞定就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAXN 1111 8 typedef long long ll; 9 int n,m; 10 ll num[MAXN]; 11 int lx[MAXN],ly[MAXN]; 12 bool mark[MAXN]; 13 vector<int>map[MAXN]; 14 15 int dfs(int u) { 16 for(int i=0; i<map[u].size(); i++) { 17 int v=map[u][i]; 18 if(!mark[v]) { 19 mark[v]=true; 20 if(ly[v]==-1||dfs(ly[v])) { 21 ly[v]=u; 22 lx[u]=v; 23 return 1; 24 } 25 } 26 } 27 return 0; 28 } 29 30 int MaxMatch() { 31 int res=0; 32 memset(lx,-1,sizeof(lx)); 33 memset(ly,-1,sizeof(ly)); 34 for(int i=1; i<=m; i++) { 35 memset(mark,false,sizeof(mark)); 36 if(lx[i]==-1)res+=dfs(i); 37 } 38 return res; 39 } 40 41 int main() { 42 int _case; 43 scanf("%d",&_case); 44 while(_case--) { 45 scanf("%d",&n); 46 m=1; 47 for(int i=1; i<=n; i++)map[i].clear(); 48 for(int i=1; i<=n; i++)scanf("%I64d",&num[i]); 49 sort(num+1,num+1+n); 50 for(int i=2; i<=n; i++)if(num[i]!=num[i-1])num[++m]=num[i]; 51 for(int i=2; i<=m; i++) { 52 for(int j=1; j<i; j++) { 53 if(num[i]%num[j]==0) 54 map[i].push_back(j); 55 } 56 } 57 int ans=MaxMatch(); 58 printf("%d\n",m-ans); 59 } 60 return 0; 61 }