hdu 3335(最小路径覆盖)

来源:互联网 发布:基本款斜挎包 知乎 编辑:程序博客网 时间:2024/05/18 21:47

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3335

思路:有矛盾的条件一般都应该往匹配这方面想:

能够整除的连边,于是答案(最小路径)==|顶点个数|-最大匹配。这儿要注意的地方就是要去掉相同的数(排序一下即可),然后就是hungry算法搞定就可以了。

 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 }
View Code

 

 

0 0
原创粉丝点击