hdu 3335(最小路径覆盖)

题目链接: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

 

 

posted @ 2013-06-01 13:55  ihge2k  阅读(183)  评论(0编辑  收藏  举报