Codevs No.1553 互斥的数

2016-05-31 21:34:15

题目链接: 互斥的数 (Codevs No.1553)

题目大意:

  给N个数,如果其中两个数满足一个数是另一个的P倍,则称它俩互斥,求一个不互斥集合的最大容量

解法:

  听说跟hash有一点关系,不会....

  还是二分图匹配吧

  转化为求最大独立集=N-最大匹配

  裸的匈牙利算法上.外加一个map大法搞搞互斥关系

 1 //互斥的数 (Codevs No.1553)
 2 //二分图匹配
 3 #include<stdio.h>
 4 #include<algorithm>
 5 #include<string.h>
 6 #include<map>
 7 using namespace std;
 8 const int maxn=100010;
 9 int match[maxn];
10 long long a[maxn];
11 map<long long,int>m;
12 struct edge 
13 {
14     int to;
15     int next;
16     edge(){}
17     edge(int to,int next):to(to),next(next){}
18 };
19 edge n[maxn*4];
20 int cnt;
21 int head[maxn];
22 bool vis[maxn];
23 int N,P;
24 void insert(int x,int y)
25 {
26     n[++cnt]=edge(y,head[x]);
27     head[x]=cnt;
28     n[++cnt]=edge(x,head[y]);
29     head[y]=cnt;
30     return ;
31 }
32 bool DFS(int x)
33 {    
34     for(int i=head[x];i;i=n[i].next)
35     {
36         if(!vis[n[i].to])
37         {
38             vis[n[i].to]=1;
39             if(match[n[i].to]==-1||DFS(match[n[i].to]))
40             {
41                 match[n[i].to]=x;
42                 match[x]=n[i].to;
43                 return 1;
44             }
45         }
46     }
47     return 0;
48 }
49 int Maxmatch()
50 {
51     int ans=0;
52     memset(match,-1,sizeof(match));
53     for(int i=1;i<=N;i++)
54     {
55         if(match[i]==-1)
56         {
57             memset(vis,0,sizeof(vis));
58             if(DFS(i))ans++;
59         }
60     }
61     return ans;
62 }
63 int main()
64 {
65     scanf("%d %d",&N,&P);
66     for(int i=1;i<=N;i++)
67     {
68         scanf("%lld",&a[i]);
69     }
70     sort(a+1,a+N+1);
71     for(int i=N;i>=1;i--)
72     {
73          m[a[i]]=i;
74          int tmp=m[P*a[i]];
75          if(tmp)insert(i,tmp);
76     }
77     printf("%d",N-Maxmatch());
78 }

 

posted @ 2016-05-31 21:39  %Neptune%  阅读(505)  评论(0编辑  收藏  举报