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

 

 

你可能感兴趣的:(HDU)